home *** CD-ROM | disk | FTP | other *** search
/ CD Shareware Magazine 1996 December / CD_shareware_12-96.iso / DOS / Programa / CCDL122.ZIP / SOURCE / ANALYZE.C next >
Encoding:
C/C++ Source or Header  |  1996-07-29  |  26.0 KB  |  733 lines

  1. /*
  2.  * 68K/386 32-bit C compiler.
  3.  *
  4.  * copyright (c) 1996, David Lindauer
  5.  * 
  6.  * This compiler is intended for educational use.  It may not be used
  7.  * for profit without the express written consent of the author.
  8.  *
  9.  * It may be freely redistributed, as long as this notice remains intact
  10.  * and sources are distributed along with any executables derived from them.
  11.  *
  12.  * The author is not responsible for damages, either direct or consequential,
  13.  * that may arise from use of this software.
  14.  *
  15.  * v1.5 August 1996
  16.  * David Lindauer, gclind01@starbase.spd.louisville.edu
  17.  *
  18.  * Credits to Mathew Brandt for original K&R C compiler
  19.  *
  20.  */
  21. #include        <stdio.h>
  22. #include        "expr.h"
  23. #include        "c.h"
  24. #include        "gen.h"
  25. #include        "cglbdec.h"
  26.  
  27. /* pc-relative expressions not optimized */
  28. extern AMODE    push[], pop[];
  29. extern OCODE    *peep_tail;
  30. extern OCODE    *entryref;
  31. extern SYM *currentfunc;
  32. extern int prm_stackcheck;
  33.  
  34. extern long framedepth,stackdepth;
  35.  
  36. int floatregs = 1,dataregs=1,addrregs = 1;
  37. /*
  38.  *      this module will step through the parse tree and find all
  39.  *      optimizable expressions. at present these expressions are
  40.  *      limited to expressions that are valid throughout the scope
  41.  *      of the function. the list of optimizable expressions is:
  42.  *
  43.  *              constants
  44.  *              global and static addresses
  45.  *              auto addresses
  46.  *              contents of auto addresses.
  47.  *
  48.  *      contents of auto addresses are valid only if the address is
  49.  *      never referred to without dereferencing.
  50.  *
  51.  *      scan will build a list of optimizable expressions which
  52.  *      opt1 will replace during the second optimization pass.
  53.  */
  54.  
  55. static CSE       *olist;         /* list of optimizable expressions */
  56.  
  57. int equalnode(ENODE *node1, ENODE *node2)
  58. /*
  59.  *      equalnode will return 1 if the expressions pointed to by
  60.  *      node1 and node2 are equivalent.
  61.  */
  62. {       if( node1 == 0 || node2 == 0 )
  63.                 return 0;
  64.         if( node1->nodetype != node2->nodetype )
  65.                 return 0;
  66.         if( (node1->nodetype == en_icon || node1->nodetype == en_labcon ||
  67.                         node1->nodetype == en_nalabcon || node1->nodetype == en_autoreg ||
  68.             node1->nodetype == en_nacon || node1->nodetype == en_napccon
  69.                         || node1->nodetype == en_autocon || node1->nodetype == en_absacon) &&
  70.             node1->v.i == node2->v.i )
  71.                 return 1;
  72.                 if (node1->nodetype == en_rcon && node1->v.f == node2->v.f)
  73.                     return 1;
  74.         if( lvalue(node1) && equalnode(node1->v.p[0], node2->v.p[0]) )
  75.                 return 1;
  76.         return 0;
  77. }
  78.  
  79. CSE *searchnode(ENODE *node)
  80. /*
  81.  *      searchnode will search the common expression table for an entry
  82.  *      that matches the node passed and return a pointer to it.
  83.  */
  84. {       CSE     *csp;
  85.         csp = olist;
  86.         while( csp != 0 ) {
  87.                 if( equalnode(node,csp->exp) )
  88.                         return csp;
  89.                 csp = csp->next;
  90.                 }
  91.         return 0;
  92. }
  93.  
  94. ENODE *copynode(ENODE *node)
  95. /*
  96.  *      copy the node passed into a new enode so it wont get
  97.  *      corrupted during substitution.
  98.  */
  99. {       ENODE    *temp;
  100.         if( node == 0 )
  101.                 return 0;
  102.         temp = xalloc(sizeof(ENODE));
  103.                 temp->cflags = node->cflags;
  104.         temp->nodetype = node->nodetype;
  105.         temp->v.p[0] = node->v.p[0];
  106.         temp->v.p[1] = node->v.p[1];
  107.         return temp;
  108. }
  109.  
  110. CSE *enternode(ENODE *node,int duse,int size)
  111. /*
  112.  *      enternode will enter a reference to an expression node into the
  113.  *      common expression table. duse is a flag indicating whether or not
  114.  *      this reference will be dereferenced.
  115.  */
  116. {       CSE      *csp;
  117.                 if (size == 0)
  118.                     size = natural_size(node);
  119.         if( (csp = searchnode(node)) == 0 ) {   /* add to tree */
  120.                 csp = xalloc(sizeof(CSE));
  121.                 csp->next = olist;
  122.                 csp->uses = 1;
  123.                                 csp->reg = -1;
  124.                 csp->duses = (duse != 0);
  125.                 csp->exp = copynode(node);
  126.                 csp->voidf = 0;
  127.                                 csp->size = size;
  128.                 olist = csp;
  129.                 return csp;
  130.                 }
  131.                 else
  132.                     if (chksize(csp->size,size))
  133.                         csp->size = size;
  134.         ++(csp->uses);
  135.         if( duse )
  136.                 ++(csp->duses);
  137.         return csp;
  138. }
  139.  
  140. CSE *voidauto(ENODE *node)
  141. /*
  142.  *      voidauto will void an auto dereference node which points to
  143.  *      the same auto constant as node.
  144.  */
  145. {       CSE      *csp;
  146.         csp = olist;
  147.         while( csp != 0 ) {
  148.                 if( lvalue(csp->exp) && equalnode(node,csp->exp->v.p[0]) ) {
  149.                         if( csp->voidf )
  150.                                 return 0;
  151.                         csp->voidf = 1;
  152.                         return csp;
  153.                         }
  154.                 csp = csp->next;
  155.                 }
  156.         return 0;
  157. }
  158.  
  159. void scanexpr(ENODE *node, int duse,int size)
  160. /*
  161.  *      scanexpr will scan the expression pointed to by node for optimizable
  162.  *      subexpressions. when an optimizable expression is found it is entered
  163.  *      into the tree. if a reference to an autocon node is scanned the
  164.  *      corresponding auto dereferenced node will be voided. duse should be
  165.  *      set if the expression will be dereferenced.
  166.  */
  167. {       CSE      *csp, *csp1;
  168.         if( node == 0 )
  169.                 return;
  170.         switch( node->nodetype ) {
  171.                 case en_rcon:
  172.                 case en_icon:
  173.                 case en_nalabcon:
  174.                 case en_napccon:
  175.                 case en_nacon:
  176.                                 case en_absacon:
  177.                         enternode(node,duse,size);
  178.                         break;
  179.                 case en_autocon:
  180.                 case en_autoreg:
  181.                         if( (csp = voidauto(node)) != 0 ) {
  182.                                 csp1 = enternode(node,duse,size);
  183.                                                                 if (csp)
  184.                                     csp1->uses = (csp1->duses += csp->uses);
  185.                                 }
  186.                         else
  187.                                 enternode(node,duse,size);
  188.                         break;
  189.                                 case en_bits:
  190.                                             scanexpr(node->v.p[0],duse,0);
  191.                                             break;
  192.                                 case en_floatref:
  193.                                 case en_doubleref:
  194.                                 case en_longdoubleref:
  195.                 case en_b_ref:
  196.                 case en_w_ref:
  197.                 case en_ul_ref:
  198.                 case en_l_ref:
  199.                 case en_ub_ref:
  200.                 case en_uw_ref:
  201.                         if( node->v.p[0]->nodetype == en_autocon
  202.                                                         || node->v.p[0]->nodetype == en_autoreg ) {
  203.                                 csp = enternode(node,duse,size);
  204.                                 if( csp && csp->voidf )
  205.                                         scanexpr(node->v.p[0],1,0);
  206.                         }
  207.                                                                     
  208.                         else
  209.                                 scanexpr(node->v.p[0],1,0);
  210.                         break;
  211.                 case en_uminus:
  212.                 case en_compl:  case en_ainc:
  213.                 case en_adec:   case en_not:
  214.                                 case en_cb: case en_cub:
  215.                                 case en_cw: case en_cuw:
  216.                                 case en_cl: case en_cul:
  217.                                 case en_cf: case en_cd: case en_cp: case en_cld:
  218.                         scanexpr(node->v.p[0],duse,0);
  219.                         break;
  220.                 case en_asadd:  case en_assub:
  221.                                                 size = natural_size(node->v.p[0]);
  222.                         scanexpr(node->v.p[0],duse,0);
  223.                         scanexpr(node->v.p[1],duse,size);
  224.                         break;
  225.                 case en_add:    case en_sub:
  226.                         scanexpr(node->v.p[0],duse,0);
  227.                         scanexpr(node->v.p[1],duse,0);
  228.                         break;
  229.                                 case en_asalsh: case en_asarsh: case en_alsh: case en_arsh:
  230.                 case en_asmul:  case en_asdiv:
  231.                 case en_asmod:  case en_aslsh:
  232.                                 case en_asumod: case en_asudiv: case en_asumul:
  233.                 case en_asrsh:  case en_asand:
  234.                 case en_assign: case en_refassign:
  235.                                                 size = natural_size(node->v.p[0]);
  236.                         scanexpr(node->v.p[0],0,0);
  237.                         scanexpr(node->v.p[1],0,size);
  238.                         break;
  239.                                 case en_void:
  240.                                 case en_pmul:        case en_pdiv:
  241.                 case en_mul:    case en_div:
  242.                 case en_umul:    case en_udiv: case en_umod:
  243.                 case en_lsh:    case en_rsh:
  244.                 case en_mod:    case en_and:
  245.                 case en_or:     case en_xor:
  246.                 case en_lor:    case en_land:
  247.                 case en_eq:     case en_ne:
  248.                 case en_gt:     case en_ge:
  249.                 case en_lt:     case en_le:
  250.                                 case en_ugt:    case en_uge: case en_ult: case en_ule:
  251.                 case en_asor:   case en_cond:
  252.                                 case en_moveblock: case en_stackblock: case en_callblock:
  253.                         scanexpr(node->v.p[0],0,0);
  254.                         scanexpr(node->v.p[1],0,0);
  255.                         break;
  256.                 case en_fcall: case en_intcall: case en_fcallb:
  257.                 case en_trapcall:
  258.                         scanexpr(node->v.p[0],1,0);
  259.                         scanexpr(node->v.p[1],0,0);
  260.                         break;
  261.                 }
  262. }
  263.  
  264. void scan(SNODE *block)
  265. /*
  266.  *      scan will gather all optimizable expressions into the expression
  267.  *      list for a block of statements.
  268.  */
  269. {       while( block != 0 ) {
  270.                 switch( block->stype ) {
  271.                         case st_return:
  272.                         case st_expr:
  273.                                 opt4(&block->exp);
  274.                                 scanexpr(block->exp,0,0);
  275.                                 break;
  276.                         case st_while:
  277.                         case st_do:
  278.                                 opt4(&block->exp);
  279.                                 scanexpr(block->exp,0,0);
  280.                                 scan(block->s1);
  281.                                 break;
  282.                         case st_for:
  283.                                 opt4(&block->label);
  284.                                 scanexpr(block->label,0,0);
  285.                                 opt4(&block->exp);
  286.                                 scanexpr(block->exp,0,0);
  287.                                 scan(block->s1);
  288.                                 opt4(&block->s2);
  289.                                 scanexpr(block->s2,0,0);
  290.                                 break;
  291.                         case st_if:
  292.                                 opt4(&block->exp);
  293.                                 scanexpr(block->exp,0,0);
  294.                                 scan(block->s1);
  295.                                 scan(block->s2);
  296.                                 break;
  297.                         case st_switch:
  298.                                 opt4(&block->exp);
  299.                                 scanexpr(block->exp,0,0);
  300.                                 scan(block->s1);
  301.                                 break;
  302.                         case st_case:
  303.                                 scan(block->s1);
  304.                                 break;
  305.                                                 case st_block:
  306.                                                                 scan(block->exp);
  307.                                                                 break;
  308.                         }
  309.                 block = block->next;
  310.                 }
  311. }
  312.  
  313. void exchange(CSE **c1)
  314. /*
  315.  *      exchange will exchange the order of two expression entries
  316.  *      following c1 in the linked list.
  317.  */
  318. {       CSE      *csp1, *csp2;
  319.         csp1 = *c1;
  320.         csp2 = csp1->next;
  321.         csp1->next = csp2->next;
  322.         csp2->next = csp1;
  323.         *c1 = csp2;
  324. }
  325.  
  326. int     desire(CSE *csp)
  327. /*
  328.  *      returns the desirability of optimization for a subexpression.
  329.  */
  330. {       if( csp->voidf || (csp->exp->nodetype == en_icon &&
  331.                         csp->exp->v.i < 16 && csp->exp->v.i >= 0))
  332.                 return 0;
  333.         if( lvalue(csp->exp) )
  334.                 return 2 * csp->uses;
  335.         return csp->uses;
  336. }
  337.  
  338. int     bsort(CSE **list)
  339. /*
  340.  *      bsort implements a bubble sort on the expression list.
  341.  */
  342. {       CSE      *csp1, *csp2;
  343.         csp1 = *list;
  344.         if( csp1 == 0 || csp1->next == 0 )
  345.                 return 0;
  346.         bsort( &(csp1->next));
  347.         csp2 = csp1->next;
  348.         if( desire(csp1) < desire(csp2) ) {
  349.                 exchange(list);
  350.                 return 1;
  351.                 }
  352.         return 0;
  353. }
  354. void reserveregs(int *datareg, int *addreg, int *floatreg)
  355. /*
  356.  * Reserve regs goes through and reserves a register for variables with
  357.  * the REGISTER keyword.  Note that it currently does register allocation
  358.  * backwards...
  359.  */
  360. {
  361.     CSE *csp = olist;
  362.  
  363.     while (csp) {
  364.         switch (csp->exp->nodetype) {
  365.                                 case en_floatref:
  366.                                 case en_doubleref:
  367.                                 case en_longdoubleref:
  368. #ifdef i386
  369.                                         break;
  370. #endif
  371.                 case en_b_ref:
  372.                 case en_w_ref:
  373.                 case en_l_ref:
  374.                 case en_ub_ref:
  375.                 case en_uw_ref:
  376.                                 case en_ul_ref:
  377.                                         if (csp->exp->v.p[0]->nodetype != en_autoreg)        
  378.                                             break;
  379.                                 case en_autoreg:
  380.                                           if (csp->exp->nodetype == en_floatref || csp->exp->nodetype == en_doubleref 
  381.                                                 || csp->exp->nodetype == en_longdoubleref) {
  382. #ifndef i386
  383.                                                 if (*floatreg <24 && floatregs)
  384.                                                     csp->reg = (*floatreg)++;
  385. #endif
  386.                                             }
  387. #ifdef i386
  388.                             else if( (csp->duses <= csp->uses / 4) && (*datareg < MAXDATA) &&dataregs)
  389.                         csp->reg = (*datareg)++;
  390.                             else if(( csp->size > 2 || csp->size <-2) && (*addreg < MAXADDRESS) && addrregs) {
  391.                         csp->reg = (*addreg)++;
  392.                                             }
  393. #else
  394.                             else if( (*datareg < MAXDATA) && (csp->duses <= csp->uses/4) && dataregs)
  395.                         csp->reg = (*datareg)++;
  396.                             else if((csp->size > 1 || csp->size < -1) && (*addreg < MAXADDRESS) &&addrregs)
  397.                         csp->reg = (*addreg)++;
  398. #endif
  399.                                             break;
  400.         }
  401.         csp = csp->next;
  402.     }
  403. }    
  404.  
  405. void allocate(int datareg, int addreg, int floatreg )
  406. /*
  407.  *      allocate will allocate registers for the expressions that have
  408.  *      a high enough desirability.
  409.  */
  410. {       CSE      *csp;
  411.         ENODE    *exptr;
  412.         unsigned      mask, rmask,i,fmask,frmask,size;
  413.         AMODE    *ap, *ap2;
  414.                 framedepth = 4;
  415.         mask = 0;
  416.                 rmask = 0;
  417.                 fmask = frmask = 0;
  418.                 for (i=FREEDATA; i < datareg; i++) {
  419.                         rmask = rmask | (1 << (15 - i));
  420.                         mask = mask | (1 << i);
  421.                 }
  422.                 for (i=FREEADDRESS+8; i < addreg; i++) {
  423.                         rmask = rmask | (1 << (15 - i));
  424.                         mask = mask | (1 << i);
  425.                 }
  426.         while( bsort(&olist) );         /* sort the expression list */
  427.         csp = olist;
  428.         while( csp != 0 ) {
  429.                         if (csp->reg == -1 && !(csp->exp->cflags & DF_VOL)) {
  430.                 if( desire(csp) < 3 )
  431.                         csp->reg = -1;
  432.                                 else {
  433.                                     if (csp->exp->nodetype == en_rcon
  434.                                               || csp->exp->nodetype == en_floatref || csp->exp->nodetype ==en_doubleref
  435.                                                 || csp->exp->nodetype == en_longdoubleref) {
  436. #ifndef i386
  437.                                         if (floatreg <24 && floatregs)
  438.                                             csp->reg = floatreg++;
  439. #endif
  440.                                     }
  441. #ifdef i386
  442.                         else if( (csp->duses <= csp->uses / 4) && (datareg < MAXDATA) &&dataregs)
  443.                       csp->reg = (datareg)++;
  444.                     else if(( csp->size >2 || csp->size < -2) && (addreg < MAXADDRESS) && addrregs) {
  445.                       csp->reg = (addreg)++;
  446.                                     }
  447. #else
  448.                         else if( (datareg < MAXDATA) && (csp->duses <= csp->uses/4) && dataregs)
  449.                     csp->reg = (datareg)++;
  450.                         else if( (csp->size > 1 || csp->size < -1) && (addreg < MAXADDRESS) &&addrregs)
  451.                       csp->reg = (addreg)++;
  452. #endif
  453.                                 }
  454.                         }
  455.             if( csp->reg != -1 )
  456.                 {
  457.                         if (csp->reg < 16) {
  458.                             rmask = rmask | (1 << (15 - csp->reg));
  459.                         mask = mask | (1 << csp->reg);
  460.                         }
  461.                         else {
  462.                             frmask = frmask | (1 << (23 - csp->reg));
  463.               fmask = fmask | (1 << (csp->reg-16));
  464.                         }
  465.                 }
  466.                 csp = csp->next;
  467.                 }
  468. #ifndef i386
  469.                 if (currentfunc->tp->lst.head !=0 && currentfunc->tp->lst.head != (SYM *)-1) {
  470.                     mask |= (1 << (LINKREG +8));
  471.                     rmask |= (1 << (15 - LINKREG -8));
  472.                     if (currentfunc->intflag) {
  473.                         mask |= 0x307;
  474.                         rmask |= 0xe0c0;
  475.                     }
  476.                 }
  477. #endif
  478. #ifdef i386
  479.                 if (currentfunc->intflag)
  480.                     gen_code(op_pushad,0,0,0);
  481.         else
  482. #endif i386
  483.                   if( mask != 0 ) 
  484. #ifdef i386
  485.                             pushregs(rmask);
  486. #else
  487.               gen_code(op_movem,4,make_mask(rmask,0,0),push);
  488. #endif
  489.         save_mask = mask;
  490.                 if (fmask!=0)
  491. #ifndef i386
  492.                 gen_code(op_fmovem,10,make_mask(frmask,0,1),push);
  493. #endif
  494.                 fsave_mask = fmask;
  495. #ifndef i386
  496.                 if (mask & (1<<(LINKREG+8)))
  497.                     gen_code(op_move,4,makeareg(0), makeareg(LINKREG));
  498. #endif
  499.                 
  500. #ifdef i386
  501.                 gen_code(op_sub,4,makedreg(ESP), make_immed(lc_maxauto));
  502.                 stackdepth +=lc_maxauto;
  503.                 framedepth +=stackdepth;
  504.                 stackdepth = 0;
  505. #else
  506.                 gen_code(op_sub,4,make_immed(lc_maxauto), makeareg(7));
  507. #endif
  508.                 entryref = peep_tail;
  509.                 if (prm_stackcheck) {
  510.                     AMODE *ap1;
  511.                     ap = set_symbol("_stackerror",1);
  512.                     ap1 = set_symbol("_stackbottom",0);
  513. #ifdef i386
  514.                     ap1->mode = am_direct;
  515.                     gen_code(op_cmp,4,makedreg(ESP),ap1);
  516.                     gen_code(op_jb,0,ap,0);
  517. #else
  518.                     ap1->mode = am_indx;
  519.                     ap1->preg = BASEREG;
  520.                     gen_code(op_cmp,4,makeareg(7),ap1);
  521.                     gen_code(op_bhi,0,ap,0);
  522. #endif
  523.                 }
  524.         csp = olist;
  525.         while( csp != 0 ) {
  526.                                 int sz;
  527.                 if( csp->reg != -1 )
  528.                         {               /* see if preload needed */
  529.                         exptr = csp->exp;
  530.                         if( !lvalue(exptr) || (exptr->v.p[0]->v.i >= 0) )
  531.                                 {
  532.                                 initstack();
  533.                                                                 sz = csp->size;
  534.                                 ap = gen_expr(exptr,F_ALL,sz);
  535. #ifdef i386
  536.                                 if( csp->reg < 8 ) {
  537.                                                                     if (ap->mode == am_dreg)
  538.                                                                         peep_tail->oper1->preg = csp->reg;
  539.                                                                     else {
  540.                                         ap2 = makedreg(csp->reg);
  541.                                                 gen_code(op_mov,sz,ap2,ap);
  542.                                                                                 do_extend(ap2,sz,4,F_DREG);
  543.                                                                     }
  544.                                                                 }
  545.                                 else
  546.                                                                     if (csp->reg < 16) {
  547.                                                                         if (ap->mode == am_dreg)
  548.                                                                             peep_tail->oper1->preg = csp->reg - 4;
  549.                                                                         else {
  550.                                             ap2 = makedreg(csp->reg - 4);
  551.                                                     gen_code(op_mov,4,ap2,ap);
  552.                                                                         }
  553.                                                                     }
  554.                                                                     else {
  555.                                                                         /* Should never get here */
  556.                                                                         diag("float reg assigned in analyze");
  557.                                                                     }
  558. #else
  559.                                 if( csp->reg < 8 ) {
  560.                                                                     if (ap->mode == am_dreg)
  561.                                                                         peep_tail->oper2->preg = csp->reg;
  562.                                                                     else {
  563.                                         ap2 = makedreg(csp->reg);
  564.                                                 gen_code(op_move,sz,ap,ap2);
  565.                                                                                 do_extend(ap2,sz,4,F_DREG);
  566.                                                                     }
  567.                                                                 }
  568.                                 else
  569.                                                                     if (csp->reg < 16) {
  570.                                                                         if (ap->mode == am_areg)
  571.                                                                             peep_tail->oper2->preg = csp->reg - 8;
  572.                                                                         else {
  573.                                             ap2 = makeareg(csp->reg - 8);
  574.                                                     gen_code(op_move,4,ap,ap2);
  575.                                                                         }
  576.                                                                     }
  577.                                                                     else {
  578.                                                                         if (ap->mode == am_freg)
  579.                                                                             peep_tail->oper2->preg = csp->reg - 16;
  580.                                                                         else {
  581.                                             ap2 = makefreg(csp->reg - 16);
  582.                                                                                     size = 8;
  583.                                                                                     if (exptr->nodetype == en_floatref)
  584.                                                                                         size = 6;
  585.                                                     gen_code(op_fmove,size,ap,ap2);
  586.                                                                         }
  587.                                                                     }
  588. #endif
  589.                                 freeop(ap);
  590.                                 }
  591.                         }
  592.                 csp = csp->next;
  593.                 }
  594. }
  595.  
  596. void repexpr(ENODE *node)
  597. /*
  598.  *      repexpr will replace all allocated references within an expression
  599.  *      with tempref nodes.
  600.  */
  601. {       CSE      *csp;
  602.         if( node == 0 )
  603.                 return;
  604.         switch( node->nodetype ) {
  605.                 case en_rcon:
  606.                 case en_icon:
  607.                 case en_nacon:
  608.                 case en_napccon:
  609.                 case en_autocon:
  610.                                 case en_autoreg:
  611.                                 case en_absacon:
  612.                         if( (csp = searchnode(node)) != 0 )
  613.                                 if( csp->reg > 0 ) {
  614.                                         node->nodetype = en_tempref;
  615.                                         node->v.i = csp->reg | (csp->size << 8);
  616.                                         }
  617.                         break;
  618.                                 case en_floatref:
  619.                                 case en_doubleref:
  620.                                 case en_longdoubleref:
  621.                 case en_ub_ref:
  622.                 case en_uw_ref:
  623.                 case en_b_ref:
  624.                 case en_w_ref:
  625.                 case en_l_ref:
  626.                 case en_ul_ref:
  627.                         if( (csp = searchnode(node)) != 0 ) {
  628.                                 if( csp->reg > 0 ) {
  629.                                         node->nodetype = en_tempref;
  630.                                         node->v.i = csp->reg | (csp->size << 8);
  631.                                         }
  632.                                 else
  633.                                         repexpr(node->v.p[0]);
  634.                                 }
  635.                         else
  636.                                 repexpr(node->v.p[0]);
  637.                         break;
  638.                 case en_uminus: case en_bits:
  639.                 case en_not:    case en_compl:
  640.                 case en_ainc:   case en_adec:
  641.                                 case en_cb: case en_cub:
  642.                                 case en_cw: case en_cuw:
  643.                                 case en_cl: case en_cul:
  644.                                 case en_cf: case en_cd: case en_cp: case en_cld:
  645.                         repexpr(node->v.p[0]);
  646.                         break;
  647.                 case en_add:    case en_sub:
  648.                 case en_umul:    case en_udiv: case en_umod:
  649.                 case en_mul:    case en_div:
  650.                 case en_mod:    case en_lsh:
  651.                                 case en_asalsh: case en_asarsh: case en_alsh: case en_arsh:
  652.                 case en_rsh:    case en_and:
  653.                 case en_or:     case en_xor:
  654.                 case en_land:   case en_lor:
  655.                 case en_eq:     case en_ne:
  656.                 case en_lt:     case en_le:
  657.                                 case en_ugt:    case en_uge: case en_ult: case en_ule:
  658.                 case en_gt:     case en_ge:
  659.                 case en_cond:   case en_void:
  660.                 case en_asadd:  case en_assub:
  661.                 case en_asmul:  case en_asdiv:
  662.                 case en_asor:   case en_asand:
  663.                 case en_asmod:  case en_aslsh:
  664.                                 case en_asumod: case en_asudiv: case en_asumul: case en_pmul:
  665.                 case en_asrsh:  case en_fcall: case en_trapcall: case en_pdiv:
  666.                 case en_assign: case en_intcall: case en_fcallb: case en_refassign:
  667.                 case en_moveblock: case en_stackblock: case en_callblock:
  668.                         repexpr(node->v.p[0]);
  669.                         repexpr(node->v.p[1]);
  670.                         break;
  671.                 }
  672. }
  673.  
  674. void repcse(SNODE *block)
  675. /*
  676.  *      repcse will scan through a block of statements replacing the
  677.  *      optimized expressions with their temporary references.
  678.  */
  679. {       while( block != 0 ) {
  680.                 switch( block->stype ) {
  681.                         case st_return:
  682.                         case st_expr:
  683.                                 repexpr(block->exp);
  684.                                 break;
  685.                         case st_while:
  686.                         case st_do:
  687.                                 repexpr(block->exp);
  688.                                 repcse(block->s1);
  689.                                 break;
  690.                         case st_for:
  691.                                 repexpr(block->label);
  692.                                 repexpr(block->exp);
  693.                                 repcse(block->s1);
  694.                                 repexpr(block->s2);
  695.                                 break;
  696.                         case st_if:
  697.                                 repexpr(block->exp);
  698.                                 repcse(block->s1);
  699.                                 repcse(block->s2);
  700.                                 break;
  701.                         case st_switch:
  702.                                 repexpr(block->exp);
  703.                                 repcse(block->s1);
  704.                                 break;
  705.                         case st_case:
  706.                                 repcse(block->s1);
  707.                                 break;
  708.                                                 case st_block:
  709.                                                                 repcse(block->exp);
  710.                                                                 break;
  711.                         }
  712.                 block = block->next;
  713.                 }
  714. }
  715.  
  716. void opt1(SNODE *block)
  717. /*
  718.  *      opt1 is the externally callable optimization routine. it will
  719.  *      collect and allocate common subexpressions and substitute the
  720.  *      tempref for all occurrances of the expression within the block.
  721.  *
  722.  *        optimizer is currently turned off...
  723.  */
  724. {
  725.         int datareg = FREEDATA;
  726.         int addreg = 8+FREEADDRESS;
  727.         int floatreg = 16 + FREEFLOAT;
  728.         olist = 0;
  729.         scan(block);            /* collect expressions */
  730.                 reserveregs(&datareg, &addreg, &floatreg);        /* Allocate register vars */
  731.         allocate(datareg, addreg,floatreg);             /* allocate registers  for opt*/
  732.         repcse(block);          /* replace allocated expressions */
  733. }