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

  1. /*********************************************************************
  2.  *$Log:    control.c,v $
  3.  * Revision 2.8  94/03/14  08:46:56  cifuente
  4.  * #ifdef MSDOS to include alloc.h
  5.  * 
  6.  * Revision 2.7  94/03/11  16:20:45  cifuente
  7.  * Fixed bug in compound conditions.
  8.  * 
  9.  * Revision 2.6  94/02/22  15:13:51  cifuente
  10.  * Modified if..then..else structuring algorithm (now it works).
  11.  * Doesn't flag nodes that require a label (this is left for the
  12.  * code generator to decide).
  13.  * 
  14.  * Revision 2.5  93/10/01  08:58:13  cifuente
  15.  * boolT type - for compilation under unix SVR4.2
  16.  * 
  17.  * Revision 2.4  93/09/20  11:49:31  cifuente
  18.  * Changed tabs to spaces
  19.  * 
  20.  * Revision 2.3  93/08/23  12:14:51  cifuente
  21.  * Interactive mode with curses
  22.  *
  23.  * Revision 2.1  93/03/30  14:50:03  cifuente
  24.  * Compiled with gcc.
  25.  *
  26.  * Revision 1.1  92/10/09  14:18:26  lederman
  27.  * Initial revision
  28.  *
  29.   Description   : Performs control flow analysis on the CFG
  30.  ********************************************************************/
  31.  
  32. #include "dcc.h"
  33. #include <stdio.h>
  34. #include <string.h>
  35. #if __BORLAND__
  36. #include <alloc.h>
  37. #else
  38. #include <malloc.h>
  39. #endif
  40.  
  41. typedef struct list {
  42.     Int         nodeIdx;    /* dfsLast index to the node */
  43.     struct list *next;
  44. } nodeList;
  45.  
  46.  
  47. #define ancestor(a,b)    ((a->dfsLastNum < b->dfsLastNum) && (a->dfsFirstNum < b->dfsFirstNum))
  48. /* there is a path on the DFST from a to b if the a was first visited in a 
  49.  * dfs, and a was later visited than b when doing the last visit of each 
  50.  * node. */
  51.  
  52.  
  53. static boolT isBackEdge (PBB p,PBB s)
  54. /* Checks if the edge (p,s) is a back edge.  If node s was visited first 
  55.  * during the dfs traversal (ie. s has a smaller dfsFirst number) or s == p,
  56.  * then it is a backedge. 
  57.  * Also incrementes the number of backedges entries to the header node. */
  58. {
  59.     if (p->dfsFirstNum >= s->dfsFirstNum)
  60.     {
  61.         s->numBackEdges++;
  62.         return (TRUE);
  63.     }
  64.     return (FALSE);
  65. }
  66.  
  67.  
  68. static Int commonDom (Int currImmDom, Int predImmDom, PPROC pProc)
  69. /* Finds the common dominator of the current immediate dominator
  70.  * currImmDom and its predecessor's immediate dominator predImmDom  */ 
  71. {
  72.     if (currImmDom == NO_DOM)
  73.        return (predImmDom);
  74.     if (predImmDom == NO_DOM)   /* predecessor is the root */
  75.        return (currImmDom);
  76.  
  77.     while ((currImmDom != NO_DOM) && (predImmDom != NO_DOM) &&
  78.            (currImmDom != predImmDom))
  79.     {
  80.        if (currImmDom < predImmDom)
  81.           predImmDom = pProc->dfsLast[predImmDom]->immedDom;
  82.        else
  83.           currImmDom = pProc->dfsLast[currImmDom]->immedDom;
  84.     }
  85.     return (currImmDom);
  86. }
  87.  
  88.  
  89. static void findImmedDom (PPROC pProc)
  90. /* Finds the immediate dominator of each node in the graph pProc->cfg. 
  91.  * Adapted version of the dominators algorithm by Hecht and Ullman; finds
  92.  * immediate dominators only.  
  93.  * Note: graph should be reducible */
  94. { PBB currNode;
  95.   Int currIdx, j, predIdx;
  96.  
  97.     for (currIdx = 0; currIdx < pProc->numBBs; currIdx++) 
  98.     {
  99.         currNode = pProc->dfsLast[currIdx]; 
  100.         if (currNode->flg & INVALID_BB)        /* Do not process invalid BBs */
  101.             continue;
  102.  
  103.         for (j = 0; j < currNode->numInEdges; j++)
  104.         {
  105.             predIdx = currNode->inEdges[j]->dfsLastNum;
  106.             if (predIdx < currIdx)
  107.                 currNode->immedDom = commonDom (currNode->immedDom, 
  108.                                                 predIdx, pProc);
  109.         }
  110.     }
  111. }
  112.  
  113.  
  114. static void insertList (nodeList **l, Int n)
  115. /* Inserts the node n to the list l. */
  116. {
  117.     nodeList *newNode;
  118.  
  119.     newNode = allocStruc(nodeList);
  120.     memset(newNode, 0, sizeof(nodeList));
  121.     newNode->nodeIdx = n;
  122.     newNode->next = *l;
  123.     *l = newNode;
  124. }
  125.  
  126.  
  127. static boolT inList (nodeList *l, Int n)
  128. /* Returns whether or not the node n (dfsLast numbering of a basic block) 
  129.  * is on the list l. */
  130. {
  131.     while (l)
  132.       if (l->nodeIdx == n)
  133.          return (TRUE);
  134.       else
  135.          l = l->next;
  136.     return (FALSE);
  137. }
  138.  
  139.  
  140. static void freeList (nodeList **l)
  141. /* Frees space allocated by the list l.  */
  142. { nodeList *next;
  143.  
  144.     if (*l)
  145.     {
  146.        next = (*l)->next;
  147.        free (*l);
  148.        *l = next;
  149.     }
  150.     *l = NULL;
  151. }
  152.  
  153.  
  154. static boolT inInt(PBB n, queue *q) 
  155. /* Returns whether the node n belongs to the queue list q. */ 
  156.     while (q)
  157.       if (q->node == n)
  158.          return (TRUE);
  159.       else
  160.          q = q->next;
  161.     return (FALSE);
  162. }
  163.  
  164.  
  165. static void findEndlessFollow (PPROC pProc, nodeList *loopNodes, PBB head)
  166. /* Finds the follow of the endless loop headed at node head (if any).
  167.  * The follow node is the closest node to the loop. */
  168. { nodeList *p;
  169.   Int j, succ;
  170.  
  171.     head->loopFollow = MAX;
  172.     p = loopNodes;
  173.     while (p != NULL)
  174.     {
  175.         for (j = 0; j < pProc->dfsLast[p->nodeIdx]->numOutEdges; j++)
  176.         {
  177.             succ = pProc->dfsLast[p->nodeIdx]->edges[j].BBptr->dfsLastNum; 
  178.             if ((! inList(loopNodes, succ)) && (succ < head->loopFollow))
  179.                 head->loopFollow = succ;
  180.         }
  181.         p = p->next;
  182.     }
  183. }
  184.  
  185.  
  186. static void findNodesInLoop(PBB latchNode,PBB head,PPROC pProc,queue *intNodes) 
  187. /* Flags nodes that belong to the loop determined by (latchNode, head) and 
  188.  * determines the type of loop.                     */
  189. { Int i, headDfsNum, intNodeType, j;
  190.   nodeList *loopNodes = NULL, p;
  191.   Int immedDom,             /* dfsLast index to immediate dominator */
  192.       thenDfs, elseDfs;        /* dsfLast index for THEN and ELSE nodes */
  193.   PBB pbb;
  194.  
  195.     /* Flag nodes in loop headed by head (except header node) */
  196.     headDfsNum = head->dfsLastNum;
  197.     head->loopHead = headDfsNum;
  198.     insertList (&loopNodes, headDfsNum);
  199.     for (i = headDfsNum + 1; i < latchNode->dfsLastNum; i++)
  200.     {
  201.         if (pProc->dfsLast[i]->flg & INVALID_BB)    /* skip invalid BBs */
  202.             continue;
  203.  
  204.         immedDom = pProc->dfsLast[i]->immedDom;
  205.         if (inList (loopNodes, immedDom) && inInt(pProc->dfsLast[i], intNodes))
  206.         {
  207.                insertList (&loopNodes, i);
  208.                if (pProc->dfsLast[i]->loopHead == NO_NODE)/*not in other loop*/
  209.                     pProc->dfsLast[i]->loopHead = headDfsNum;
  210.         }
  211.     }
  212.     latchNode->loopHead = headDfsNum;
  213.     if (latchNode != head)
  214.         insertList (&loopNodes, latchNode->dfsLastNum);
  215.  
  216.     /* Determine type of loop and follow node */
  217.     intNodeType = head->nodeType;
  218.     if (latchNode->nodeType == TWO_BRANCH)
  219.        if ((intNodeType == TWO_BRANCH) || (latchNode == head))
  220.           if ((latchNode == head) ||
  221.               (inList (loopNodes, head->edges[THEN].BBptr->dfsLastNum) &&
  222.                   inList (loopNodes, head->edges[ELSE].BBptr->dfsLastNum)))
  223.           {
  224.             head->loopType = REPEAT_TYPE;
  225.             if (latchNode->edges[0].BBptr == head)
  226.                head->loopFollow = latchNode->edges[ELSE].BBptr->dfsLastNum;
  227.             else
  228.                head->loopFollow = latchNode->edges[THEN].BBptr->dfsLastNum;
  229.             pProc->Icode.SetLlFlag(latchNode->start + latchNode->length - 1,
  230.                 JX_LOOP);
  231.           }
  232.           else
  233.           {
  234.              head->loopType = WHILE_TYPE;
  235.             if (inList (loopNodes, head->edges[THEN].BBptr->dfsLastNum))
  236.                 head->loopFollow = head->edges[ELSE].BBptr->dfsLastNum; 
  237.             else
  238.                 head->loopFollow = head->edges[THEN].BBptr->dfsLastNum; 
  239.             pProc->Icode.SetLlFlag(head->start + head->length - 1, JX_LOOP);
  240.           }
  241.        else /* head = anything besides 2-way, latch = 2-way */ 
  242.        {
  243.             head->loopType = REPEAT_TYPE;
  244.             if (latchNode->edges[THEN].BBptr == head)
  245.                 head->loopFollow = latchNode->edges[ELSE].BBptr->dfsLastNum;
  246.             else
  247.                 head->loopFollow = latchNode->edges[THEN].BBptr->dfsLastNum;
  248.             pProc->Icode.SetLlFlag(latchNode->start + latchNode->length - 1,
  249.                 JX_LOOP);
  250.        }
  251.     else    /* latch = 1-way */
  252.         if (latchNode->nodeType == LOOP_NODE)
  253.         {
  254.             head->loopType = REPEAT_TYPE; 
  255.             head->loopFollow = latchNode->edges[0].BBptr->dfsLastNum;
  256.         }
  257.         else if (intNodeType == TWO_BRANCH)
  258.         {
  259.             head->loopType = WHILE_TYPE;
  260.             pbb = latchNode; 
  261.             thenDfs = head->edges[THEN].BBptr->dfsLastNum;
  262.             elseDfs = head->edges[ELSE].BBptr->dfsLastNum;
  263.             while (1)
  264.             {
  265.                 if (pbb->dfsLastNum == thenDfs)
  266.                 {
  267.                     head->loopFollow = elseDfs;
  268.                     break;
  269.                 }
  270.                 else if (pbb->dfsLastNum == elseDfs)
  271.                 {
  272.                     head->loopFollow = thenDfs;
  273.                     break;
  274.                 }
  275.  
  276.                 /* Check if couldn't find it, then it is a strangely formed
  277.                  * loop, so it is safer to consider it an endless loop */
  278.                 if (pbb->dfsLastNum <= head->dfsLastNum)
  279.                 {
  280.                     head->loopType = ENDLESS_TYPE;
  281.                     findEndlessFollow (pProc, loopNodes, head);
  282.                     break;
  283.                 }
  284.                 pbb = pProc->dfsLast[pbb->immedDom];    
  285.             }
  286.             if (pbb->dfsLastNum > head->dfsLastNum)
  287.                 pProc->dfsLast[head->loopFollow]->loopHead = NO_NODE;    /*****/
  288.             pProc->Icode.SetLlFlag(head->start + head->length - 1, JX_LOOP);
  289.         }
  290.         else
  291.         {
  292.             head->loopType = ENDLESS_TYPE;
  293.             findEndlessFollow (pProc, loopNodes, head);
  294.         }
  295.  
  296.     freeList(&loopNodes);
  297. }
  298.  
  299.  
  300. static void findNodesInInt (queue **intNodes, Int level, interval *Ii)
  301. /* Recursive procedure to find nodes that belong to the interval (ie. nodes 
  302.  * from G1).                                */
  303. { queue *l;
  304.  
  305.     if (level == 1)
  306.        for (l = Ii->nodes; l; l = l->next)
  307.           appendQueue (intNodes, l->node);
  308.     else
  309.        for (l = Ii->nodes; l; l= l->next)
  310.           findNodesInInt (intNodes, level - 1, l->node->correspInt);
  311. }
  312.  
  313.  
  314. static void structLoops(PPROC pProc, derSeq *derivedG)
  315. /* Algorithm for structuring loops */
  316. { interval *Ii;
  317.   PBB intHead,          /* interval header node             */
  318.       pred,             /* predecessor node                 */ 
  319.       latchNode;        /* latching node (in case of loops) */
  320.   Int i,                /* counter                          */ 
  321.       level = 0;        /* derived sequence level           */
  322.   interval *initInt;    /* initial interval                 */
  323.   queue *intNodes;      /* list of interval nodes           */
  324.  
  325.     /* Structure loops */
  326.     while (derivedG)    /* for all derived sequences Gi */
  327.     {
  328.        level++;
  329.        Ii = derivedG->Ii;
  330.        while (Ii)       /* for all intervals Ii of Gi */
  331.        {
  332.           latchNode = NULL;
  333.           intNodes  = NULL;
  334.  
  335.           /* Find interval head (original BB node in G1) and create
  336.            * list of nodes of interval Ii.              */
  337.           initInt = Ii;
  338.           for (i = 1; i < level; i++)
  339.               initInt = initInt->nodes->node->correspInt;
  340.           intHead = initInt->nodes->node;
  341.  
  342.           /* Find nodes that belong to the interval (nodes from G1) */
  343.           findNodesInInt (&intNodes, level, Ii);
  344.  
  345.           /* Find greatest enclosing back edge (if any) */
  346.           for (i = 0; i < intHead->numInEdges; i++)
  347.           {
  348.               pred = intHead->inEdges[i]; 
  349.               if (inInt(pred, intNodes) && isBackEdge(pred, intHead))
  350.                  if (! latchNode)
  351.                     latchNode = pred;
  352.                  else
  353.                  {
  354.                     if (pred->dfsLastNum > latchNode->dfsLastNum)
  355.                            latchNode = pred;
  356.                  }
  357.           }
  358.  
  359.           /* Find nodes in the loop and the type of loop */
  360.           if (latchNode)
  361.           { 
  362.              /* Check latching node is at the same nesting level of case
  363.                * statements (if any) and that the node doesn't belong to
  364.                * another loop.                   */
  365.              if ((latchNode->caseHead == intHead->caseHead) &&
  366.                  (latchNode->loopHead == NO_NODE)) 
  367.              {
  368.                 intHead->latchNode = latchNode->dfsLastNum;
  369.                 findNodesInLoop(latchNode, intHead, pProc, intNodes);
  370.                 latchNode->flg |= IS_LATCH_NODE;
  371.              }
  372.           }
  373.  
  374.           /* Next interval */
  375.           Ii = Ii->next;
  376.        }
  377.  
  378.        /* Next derived sequence */
  379.        derivedG = derivedG->next;
  380.     }
  381. }
  382.  
  383.  
  384. static boolT successor (Int s, Int h, PPROC pProc)
  385. /* Returns whether the BB indexed by s is a successor of the BB indexed by
  386.  * h.  Note that h is a case node.                  */
  387. { Int i;
  388.   PBB header;
  389.  
  390.     header = pProc->dfsLast[h];
  391.     for (i = 0; i < header->numOutEdges; i++)
  392.       if (header->edges[i].BBptr->dfsLastNum == s)
  393.          return (TRUE);
  394.     return (FALSE);
  395. }
  396.  
  397.  
  398. static void tagNodesInCase (PBB pBB, nodeList **l, Int head, Int tail)
  399. /* Recursive procedure to tag nodes that belong to the case described by
  400.  * the list l, head and tail (dfsLast index to first and exit node of the 
  401.  * case).                               */
  402. { Int current,      /* index to current node */
  403.       i;
  404.  
  405.     pBB->traversed = DFS_CASE;
  406.     current = pBB->dfsLastNum;
  407.     if ((current != tail) && (pBB->nodeType != MULTI_BRANCH) && 
  408.         (inList (*l, pBB->immedDom)))
  409.     {
  410.        insertList (l, current);
  411.        pBB->caseHead = head;
  412.        for (i = 0; i < pBB->numOutEdges; i++)
  413.           if (pBB->edges[i].BBptr->traversed != DFS_CASE)
  414.              tagNodesInCase (pBB->edges[i].BBptr, l, head, tail);
  415.     }
  416. }
  417.  
  418.  
  419. static void structCases(PPROC pProc)
  420. /* Structures case statements.  This procedure is invoked only when pProc
  421.  * has a case node.                         */
  422. { Int i, j;
  423.   PBB caseHeader;               /* case header node         */
  424.   Int exitNode = NO_NODE;       /* case exit node           */
  425.   nodeList *caseNodes = NULL;   /* temporary: list of nodes in case */
  426.  
  427.     /* Linear scan of the nodes in reverse dfsLast order, searching for
  428.      * case nodes                           */
  429.     for (i = pProc->numBBs - 1; i >= 0; i--)
  430.         if (pProc->dfsLast[i]->nodeType == MULTI_BRANCH)
  431.         {
  432.             caseHeader = pProc->dfsLast[i];
  433.  
  434.             /* Find descendant node which has as immediate predecessor 
  435.              * the current header node, and is not a successor.    */
  436.             for (j = i + 2; j < pProc->numBBs; j++)
  437.             {
  438.                 if ((!successor(j, i, pProc)) && 
  439.                                         (pProc->dfsLast[j]->immedDom == i))
  440.                     if (exitNode == NO_NODE)
  441.                           exitNode = j;
  442.                     else if (pProc->dfsLast[exitNode]->numInEdges <
  443.                              pProc->dfsLast[j]->numInEdges) 
  444.                           exitNode = j;
  445.              }
  446.             pProc->dfsLast[i]->caseTail = exitNode;
  447.          
  448.             /* Tag nodes that belong to the case by recording the
  449.              * header field with caseHeader.           */
  450.             insertList (&caseNodes, i); 
  451.             pProc->dfsLast[i]->caseHead = i;
  452.             for (j = 0; j < caseHeader->numOutEdges; j++)
  453.                 tagNodesInCase (caseHeader->edges[j].BBptr, &caseNodes, i,
  454.                                 exitNode);
  455.             if (exitNode != NO_NODE)
  456.                 pProc->dfsLast[exitNode]->caseHead = i;
  457.         }
  458. }
  459.  
  460.  
  461. static void flagNodes (nodeList **l, Int f, PPROC pProc)
  462. /* Flags all nodes in the list l as having follow node f, and deletes all
  463.  * nodes from the list.                         */
  464. {  nodeList *p;
  465.  
  466.     p = *l;
  467.     while (p)
  468.     {
  469.        pProc->dfsLast[p->nodeIdx]->ifFollow = f;
  470.        p = p->next;
  471.        free (*l);
  472.        *l = p;
  473.     }
  474.     *l = NULL;
  475. }
  476.  
  477.  
  478. static void structIfs (PPROC pProc)
  479. /* Structures if statements */
  480. {  Int curr,                    /* Index for linear scan of nodes       */
  481.        desc,                    /* Index for descendant                 */
  482.        followInEdges,            /* Largest # in-edges so far             */
  483.        follow;                  /* Possible follow node                 */
  484.    nodeList *domDesc = NULL,    /* List of nodes dominated by curr      */
  485.         *unresolved = NULL,     /* List of unresolved if nodes          */
  486.         *l;                     /* Temporary list                       */
  487.    PBB currNode,                /* Pointer to current node              */
  488.         pbb;
  489.  
  490.     /* Linear scan of nodes in reverse dfsLast order */
  491.     for (curr = pProc->numBBs - 1; curr >= 0; curr--)
  492.     {
  493.         currNode = pProc->dfsLast[curr];
  494.         if (currNode->flg & INVALID_BB)        /* Do not process invalid BBs */
  495.             continue;
  496.  
  497.         if ((currNode->nodeType == TWO_BRANCH) &&
  498.             (! (pProc->Icode.GetLlFlag(currNode->start + currNode->length - 1)
  499.                 & JX_LOOP)))
  500.         {
  501.             followInEdges = 0;
  502.             follow = 0;
  503.  
  504.             /* Find all nodes that have this node as immediate dominator */
  505.             for (desc = curr+1; desc < pProc->numBBs; desc++)
  506.             {
  507.                 if (pProc->dfsLast[desc]->immedDom == curr)  {
  508.                     insertList (&domDesc, desc);
  509.                     pbb = pProc->dfsLast[desc];
  510.                     if ((pbb->numInEdges - pbb->numBackEdges) >= followInEdges)
  511.                     {
  512.                         follow = desc;
  513.                         followInEdges = pbb->numInEdges - pbb->numBackEdges;
  514.                     }
  515.                 }
  516.             }
  517.  
  518.             /* Determine follow according to number of descendants
  519.              * immediately dominated by this node  */
  520.             if ((follow != 0) && (followInEdges > 1))
  521.             {
  522.                 currNode->ifFollow = follow;
  523.                 if (unresolved)
  524.                     flagNodes (&unresolved, follow, pProc);
  525.             }
  526.             else
  527.                 insertList (&unresolved, curr);
  528.         }
  529.         freeList (&domDesc);
  530.     }
  531. }
  532.  
  533.  
  534. void compoundCond (PPROC pproc)
  535. /* Checks for compound conditions of basic blocks that have only 1 high 
  536.  * level instruction.  Whenever these blocks are found, they are merged
  537.  * into one block with the appropriate condition */
  538. { Int i, j, k, numOutEdges;
  539.   PBB pbb, t, e, obb, pred;
  540.   PICODE picode, ticode;
  541.   COND_EXPR *exp;
  542.  TYPEADR_TYPE *edges;
  543.   boolT change;
  544.  
  545.   change = TRUE;
  546.   while (change)
  547.   {
  548.     change = FALSE;
  549.  
  550.     /* Traverse nodes in postorder, this way, the header node of a
  551.      * compound condition is analysed first */
  552.     for (i = 0; i < pproc->numBBs; i++)
  553.     {
  554.         pbb = pproc->dfsLast[i];
  555.         if (pbb->flg & INVALID_BB)
  556.             continue;
  557.  
  558.         if (pbb->nodeType == TWO_BRANCH)
  559.         {
  560.             t = pbb->edges[THEN].BBptr;
  561.             e = pbb->edges[ELSE].BBptr;
  562.  
  563.             /* Check (X || Y) case */
  564.             if ((t->nodeType == TWO_BRANCH) && (t->numHlIcodes == 1) && 
  565.                 (t->numInEdges == 1) && (t->edges[ELSE].BBptr == e)) 
  566.             {
  567.                 obb = t->edges[THEN].BBptr;
  568.  
  569.                 /* Construct compound DBL_OR expression */
  570.                 picode = pproc->Icode.GetIcode(pbb->start + pbb->length -1);
  571.                 ticode = pproc->Icode.GetIcode(t->start + t->length -1);
  572.                 exp = boolCondExp (picode->ic.hl.oper.exp,
  573.                                    ticode->ic.hl.oper.exp, DBL_OR);
  574.                 picode->ic.hl.oper.exp = exp;
  575.  
  576.                 /* Replace in-edge to obb from t to pbb */
  577.                 for (j = 0; j < obb->numInEdges; j++)
  578.                     if (obb->inEdges[j] == t)
  579.                     {
  580.                         obb->inEdges[j] = pbb;
  581.                         break;
  582.                     }
  583.  
  584.                 /* New THEN out-edge of pbb */
  585.                 pbb->edges[THEN].BBptr = obb;
  586.  
  587.                 /* Remove in-edge t to e */
  588.                 for (j = 0; j < (e->numInEdges-1); j++)
  589.                     if (e->inEdges[j] == t)
  590.                     {
  591.                         memmove (&e->inEdges[j], &e->inEdges[j+1], 
  592.                                  (size_t)((e->numInEdges - j - 1) * sizeof(PBB)));
  593.                         break;
  594.                     }
  595.                 e->numInEdges--;    /* looses 1 arc */
  596.                 t->flg |= INVALID_BB;
  597.  
  598.                 if (pbb->flg & IS_LATCH_NODE)
  599.                     pproc->dfsLast[t->dfsLastNum] = pbb;
  600.                 else 
  601.                     i--;        /* to repeat this analysis */
  602.  
  603.                 change = TRUE;
  604.             }
  605.  
  606.             /* Check (!X && Y) case */
  607.             else if ((t->nodeType == TWO_BRANCH) && (t->numHlIcodes == 1) && 
  608.                 (t->numInEdges == 1) && (t->edges[THEN].BBptr == e)) 
  609.             {
  610.                 obb = t->edges[ELSE].BBptr;
  611.  
  612.                 /* Construct compound DBL_AND expression */
  613.                 picode = pproc->Icode.GetIcode(pbb->start + pbb->length -1);
  614.                 ticode = pproc->Icode.GetIcode(t->start + t->length -1);
  615.                 inverseCondOp (&picode->ic.hl.oper.exp);
  616.                 exp = boolCondExp (picode->ic.hl.oper.exp,
  617.                                    ticode->ic.hl.oper.exp, DBL_AND);
  618.                 picode->ic.hl.oper.exp = exp;
  619.  
  620.                 /* Replace in-edge to obb from t to pbb */
  621.                 for (j = 0; j < obb->numInEdges; j++)
  622.                     if (obb->inEdges[j] == t)
  623.                     {
  624.                         obb->inEdges[j] = pbb;
  625.                         break;
  626.                     }
  627.  
  628.                 /* New THEN and ELSE out-edges of pbb */
  629.                 pbb->edges[THEN].BBptr = e;
  630.                 pbb->edges[ELSE].BBptr = obb;
  631.                 
  632.                 /* Remove in-edge t to e */
  633.                 for (j = 0; j < (e->numInEdges-1); j++)
  634.                     if (e->inEdges[j] == t)
  635.                     {
  636.                         memmove (&e->inEdges[j], &e->inEdges[j+1], 
  637.                                  (size_t)((e->numInEdges - j - 1) * sizeof(PBB)));
  638.                         break;
  639.                     }
  640.                 e->numInEdges--;    /* looses 1 arc */
  641.                 t->flg |= INVALID_BB;
  642.  
  643.                 if (pbb->flg & IS_LATCH_NODE)
  644.                     pproc->dfsLast[t->dfsLastNum] = pbb;
  645.                 else 
  646.                     i--;        /* to repeat this analysis */
  647.  
  648.                 change = TRUE;
  649.             }
  650.  
  651.             /* Check (X && Y) case */
  652.             else if ((e->nodeType == TWO_BRANCH) && (e->numHlIcodes == 1) && 
  653.                      (e->numInEdges == 1) && (e->edges[THEN].BBptr == t)) 
  654.             {
  655.                 obb = e->edges[ELSE].BBptr;
  656.  
  657.                 /* Construct compound DBL_AND expression */
  658.                 picode = pproc->Icode.GetIcode(pbb->start + pbb->length -1);
  659.                 ticode = pproc->Icode.GetIcode(t->start + t->length -1);
  660.                 exp = boolCondExp (picode->ic.hl.oper.exp,
  661.                                    ticode->ic.hl.oper.exp, DBL_AND);
  662.                 picode->ic.hl.oper.exp = exp;
  663.                 
  664.                 /* Replace in-edge to obb from e to pbb */
  665.                 for (j = 0; j < obb->numInEdges; j++)
  666.                     if (obb->inEdges[j] == e)
  667.                     {
  668.                         obb->inEdges[j] = pbb;
  669.                         break;
  670.                     }
  671.  
  672.                 /* New ELSE out-edge of pbb */
  673.                 pbb->edges[ELSE].BBptr = obb;
  674.  
  675.                 /* Remove in-edge e to t */
  676.                 for (j = 0; j < (t->numInEdges-1); j++)
  677.                     if (t->inEdges[j] == e)
  678.                     {
  679.                         memmove (&t->inEdges[j], &t->inEdges[j+1], 
  680.                                  (size_t)((t->numInEdges - j - 1) * sizeof(PBB)));
  681.                         break;
  682.                     }
  683.                 t->numInEdges--;    /* looses 1 arc */
  684.                 e->flg |= INVALID_BB;
  685.  
  686.                 if (pbb->flg & IS_LATCH_NODE)
  687.                     pproc->dfsLast[e->dfsLastNum] = pbb;
  688.                 else 
  689.                     i--;        /* to repeat this analysis */
  690.  
  691.                 change = TRUE;
  692.             }
  693.  
  694.             /* Check (!X || Y) case */
  695.             else if ((e->nodeType == TWO_BRANCH) && (e->numHlIcodes == 1) && 
  696.                      (e->numInEdges == 1) && (e->edges[ELSE].BBptr == t)) 
  697.             {
  698.                 obb = e->edges[THEN].BBptr;
  699.  
  700.                 /* Construct compound DBL_OR expression */
  701.                 picode = pproc->Icode.GetIcode(pbb->start + pbb->length -1);
  702.                 ticode = pproc->Icode.GetIcode(t->start + t->length -1);
  703.                 inverseCondOp (&picode->ic.hl.oper.exp);
  704.                 exp = boolCondExp (picode->ic.hl.oper.exp,
  705.                                    ticode->ic.hl.oper.exp, DBL_OR);
  706.                 picode->ic.hl.oper.exp = exp;
  707.                 
  708.                 /* Replace in-edge to obb from e to pbb */
  709.                 for (j = 0; j < obb->numInEdges; j++)
  710.                     if (obb->inEdges[j] == e)
  711.                     {
  712.                         obb->inEdges[j] = pbb;
  713.                         break;
  714.                     }
  715.  
  716.                 /* New THEN and ELSE out-edges of pbb */
  717.                 pbb->edges[THEN].BBptr = obb;
  718.                 pbb->edges[ELSE].BBptr = t;
  719.  
  720.                 /* Remove in-edge e to t */
  721.                 for (j = 0; j < (t->numInEdges-1); j++)
  722.                     if (t->inEdges[j] == e)
  723.                     {
  724.                         memmove (&t->inEdges[j], &t->inEdges[j+1], 
  725.                                  (size_t)((t->numInEdges - j - 1) * sizeof(PBB)));
  726.                         break;
  727.                     }
  728.                 t->numInEdges--;    /* looses 1 arc */
  729.                 e->flg |= INVALID_BB;
  730.  
  731.                 if (pbb->flg & IS_LATCH_NODE)
  732.                     pproc->dfsLast[e->dfsLastNum] = pbb;
  733.                 else 
  734.                     i--;        /* to repeat this analysis */
  735.  
  736.                 change = TRUE;
  737.             }
  738.         }
  739.     }
  740.   }
  741. }
  742.  
  743.  
  744. void structure(PPROC pProc, derSeq *derivedG)
  745. /* Structuring algorithm to find the structures of the graph pProc->cfg */
  746. {
  747.     /* Find immediate dominators of the graph */
  748.     findImmedDom(pProc);
  749.     if (pProc->hasCase)
  750.        structCases(pProc); 
  751.     structLoops(pProc, derivedG); 
  752.     structIfs(pProc); 
  753. }
  754.