Extended the semantics of the critical keyword to include
[fw/sdcc] / src / SDCCopt.c
1 /*-------------------------------------------------------------------------
2   SDCCopt.c - calls all the optimizations routines and does some of the
3               hackier transformations, these include translating iCodes
4               to function calls and replacing local variables with their
5               register equivalents etc. Also contains the driver routine
6               for dead code elimination
7
8              Written By -  Sandeep Dutta . sandeep.dutta@usa.net (1998)
9
10    This program is free software; you can redistribute it and/or modify it
11    under the terms of the GNU General Public License as published by the
12    Free Software Foundation; either version 2, or (at your option) any
13    later version.
14    
15    This program is distributed in the hope that it will be useful,
16    but WITHOUT ANY WARRANTY; without even the implied warranty of
17    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18    GNU General Public License for more details.
19    
20    You should have received a copy of the GNU General Public License
21    along with this program; if not, write to the Free Software
22    Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
23    
24    In other words, you are welcome to use, share and improve this program.
25    You are forbidden to forbid anyone else to use, share and improve
26    what you give them.   Help stamp out software-hoarding!  
27 -------------------------------------------------------------------------*/
28
29 #include "common.h"
30
31 /*-----------------------------------------------------------------*/
32 /* global variables */
33 int cseDefNum = 0;
34
35 char flowChanged = 0;
36
37
38 /*-----------------------------------------------------------------*/
39 /* printSymName - prints the symbol names                          */
40 /*-----------------------------------------------------------------*/
41 int 
42 printSymName (void *vsym)
43 {
44   symbol *sym = vsym;
45   fprintf (stdout, " %s ", sym->name);
46   return 0;
47 }
48
49 /*-----------------------------------------------------------------*/
50 /* cnvToFcall - does the actual conversion to function call        */
51 /*-----------------------------------------------------------------*/
52 static void 
53 cnvToFcall (iCode * ic, eBBlock * ebp)
54 {
55   iCode *ip;
56   iCode *newic;
57   operand *left;
58   operand *right;
59   symbol *func = NULL;
60   int lineno = ic->lineno;
61   int bytesPushed=0;
62
63   ip = ic->next;                /* insertion point */
64   /* remove it from the iCode */
65   remiCodeFromeBBlock (ebp, ic);
66
67   left = IC_LEFT (ic);
68   right = IC_RIGHT (ic);
69
70   switch (ic->op)
71     {
72     case '+':
73       func = __fsadd;
74       break;
75     case '-':
76       func = __fssub;
77       break;
78     case '/':
79       func = __fsdiv;
80       break;
81     case '*':
82       func = __fsmul;
83       break;
84     case EQ_OP:
85       func = __fseq;
86       break;
87     case NE_OP:
88       func = __fsneq;
89       break;
90     case '<':
91       func = __fslt;
92       break;
93     case '>':
94       func = __fsgt;
95       break;
96     case LE_OP:
97       func = __fslteq;
98       break;
99     case GE_OP:
100       func = __fsgteq;
101       break;
102     }
103
104   /* if float support routines NOT compiled as reentrant */
105   if (!options.float_rent)
106     {
107
108       /* first one */
109       if (IS_REGPARM (FUNC_ARGS(func->type)->etype))
110         {
111           newic = newiCode (SEND, IC_LEFT (ic), NULL);
112           newic->argreg = SPEC_ARGREG(FUNC_ARGS(func->type)->etype);
113         }
114       else
115         {
116           newic = newiCode ('=', NULL, IC_LEFT (ic));
117           IC_RESULT (newic) = operandFromValue (FUNC_ARGS(func->type));
118         }
119
120       addiCodeToeBBlock (ebp, newic, ip);
121       newic->lineno = lineno;
122
123       /* second one */
124       if (IS_REGPARM (FUNC_ARGS(func->type)->next->etype))
125         {
126           newic = newiCode (SEND, IC_RIGHT (ic), NULL);
127           newic->argreg = SPEC_ARGREG(FUNC_ARGS(func->type)->next->etype);
128         }
129       else
130         {
131           newic = newiCode ('=', NULL, IC_RIGHT (ic));
132           IC_RESULT (newic) = operandFromValue (FUNC_ARGS(func->type)->next);
133         }
134       addiCodeToeBBlock (ebp, newic, ip);
135       newic->lineno = lineno;
136
137     }
138   else
139     {
140
141       /* push right */
142       if (IS_REGPARM (FUNC_ARGS(func->type)->next->etype))
143         {
144           newic = newiCode (SEND, right, NULL);
145           newic->argreg = SPEC_ARGREG(FUNC_ARGS(func->type)->next->etype);
146         }
147       else
148         {
149           newic = newiCode (IPUSH, right, NULL);
150           newic->parmPush = 1;
151           //bytesPushed+=4;
152           bytesPushed += getSize(operandType(right));
153         }
154
155       addiCodeToeBBlock (ebp, newic, ip);
156       newic->lineno = lineno;
157
158       /* insert push left */
159       if (IS_REGPARM (FUNC_ARGS(func->type)->etype))
160         {
161           newic = newiCode (SEND, left, NULL);
162           newic->argreg = SPEC_ARGREG(FUNC_ARGS(func->type)->etype);
163         }
164       else
165         {
166           newic = newiCode (IPUSH, left, NULL);
167           newic->parmPush = 1;
168           //bytesPushed+=4;
169           bytesPushed += getSize(operandType(left));
170         }
171       addiCodeToeBBlock (ebp, newic, ip);
172       newic->lineno = lineno;
173     }
174   /* insert the call */
175   newic = newiCode (CALL, operandFromSymbol (func), NULL);
176   IC_RESULT (newic) = IC_RESULT (ic);
177   newic->lineno = lineno;
178   newic->parmBytes+=bytesPushed;
179   addiCodeToeBBlock (ebp, newic, ip);
180 }
181
182 /*-----------------------------------------------------------------*/
183 /* cnvToFloatCast - converts casts to floats to function calls     */
184 /*-----------------------------------------------------------------*/
185 static void 
186 cnvToFloatCast (iCode * ic, eBBlock * ebp)
187 {
188   iCode *ip, *newic;
189   symbol *func = NULL;
190   sym_link *type = operandType (IC_RIGHT (ic));
191   int linenno = ic->lineno;
192   int bwd, su;
193   int bytesPushed=0;
194
195   ip = ic->next;
196   /* remove it from the iCode */
197   remiCodeFromeBBlock (ebp, ic);
198   /* depending on the type */
199   for (bwd = 0; bwd < 3; bwd++)
200     {
201       for (su = 0; su < 2; su++)
202         {
203           if (compareType (type, __multypes[bwd][su]) == 1)
204             {
205               func = __conv[0][bwd][su];
206               goto found;
207             }
208         }
209     }
210   assert (0);
211 found:
212
213   /* if float support routines NOT compiled as reentrant */
214   if (!options.float_rent)
215     {
216       /* first one */
217         if (IS_REGPARM (FUNC_ARGS(func->type)->etype)) 
218             {
219                 newic = newiCode (SEND, IC_RIGHT (ic), NULL);
220                 newic->argreg = SPEC_ARGREG(FUNC_ARGS(func->type)->etype);
221             }
222       else
223         {
224           newic = newiCode ('=', NULL, IC_RIGHT (ic));
225           IC_RESULT (newic) = operandFromValue (FUNC_ARGS(func->type));
226         }
227       addiCodeToeBBlock (ebp, newic, ip);
228       newic->lineno = linenno;
229
230     }
231   else
232     {
233       /* push the left */
234         if (IS_REGPARM (FUNC_ARGS(func->type)->etype)) {
235             newic = newiCode (SEND, IC_RIGHT (ic), NULL);
236             newic->argreg = SPEC_ARGREG(FUNC_ARGS(func->type)->etype);
237         }
238       else
239         {
240           newic = newiCode (IPUSH, IC_RIGHT (ic), NULL);
241           newic->parmPush = 1;
242           bytesPushed += getSize(operandType(IC_RIGHT(ic)));
243         }
244       addiCodeToeBBlock (ebp, newic, ip);
245       newic->lineno = linenno;
246
247     }
248
249   /* make the call */
250   newic = newiCode (CALL, operandFromSymbol (func), NULL);
251   IC_RESULT (newic) = IC_RESULT (ic);
252   newic->parmBytes+=bytesPushed;
253   addiCodeToeBBlock (ebp, newic, ip);
254   newic->lineno = linenno;
255
256 }
257
258 /*-----------------------------------------------------------------*/
259 /* cnvFromFloatCast - converts casts From floats to function calls */
260 /*-----------------------------------------------------------------*/
261 static void 
262 cnvFromFloatCast (iCode * ic, eBBlock * ebp)
263 {
264   iCode *ip, *newic;
265   symbol *func = NULL;
266   sym_link *type = operandType (IC_LEFT (ic));
267   int lineno = ic->lineno;
268   int bwd, su;
269   int bytesPushed=0;
270
271   ip = ic->next;
272   /* remove it from the iCode */
273   remiCodeFromeBBlock (ebp, ic);
274
275   /* depending on the type */
276   for (bwd = 0; bwd < 3; bwd++)
277     {
278       for (su = 0; su < 2; su++)
279         {
280           if (compareType (type, __multypes[bwd][su]) == 1)
281             {
282               func = __conv[1][bwd][su];
283               goto found;
284             }
285         }
286     }
287   assert (0);
288 found:
289
290   /* if float support routines NOT compiled as reentrant */
291   if (!options.float_rent)
292     {
293       /* first one */
294         if (IS_REGPARM (FUNC_ARGS(func->type)->etype)) {
295             newic = newiCode (SEND, IC_RIGHT (ic), NULL);
296             newic->argreg = SPEC_ARGREG(FUNC_ARGS(func->type)->etype);
297         }
298       else
299         {
300           newic = newiCode ('=', NULL, IC_RIGHT (ic));
301           IC_RESULT (newic) = operandFromValue (FUNC_ARGS(func->type));
302         }
303       addiCodeToeBBlock (ebp, newic, ip);
304       newic->lineno = lineno;
305
306     }
307   else
308     {
309
310       /* push the left */
311         if (IS_REGPARM (FUNC_ARGS(func->type)->etype)) {
312             newic = newiCode (SEND, IC_RIGHT (ic), NULL);
313             newic->argreg = SPEC_ARGREG(FUNC_ARGS(func->type)->etype);
314         }
315       else
316         {
317           newic = newiCode (IPUSH, IC_RIGHT (ic), NULL);
318           newic->parmPush = 1;
319           bytesPushed += getSize(operandType(IC_RIGHT(ic)));
320         }
321       addiCodeToeBBlock (ebp, newic, ip);
322       newic->lineno = lineno;
323
324     }
325
326   /* make the call */
327   newic = newiCode (CALL, operandFromSymbol (func), NULL);
328   IC_RESULT (newic) = IC_RESULT (ic);
329   newic->parmBytes+=bytesPushed;
330   addiCodeToeBBlock (ebp, newic, ip);
331   newic->lineno = lineno;
332
333 }
334
335 extern operand *geniCodeRValue (operand *, bool);
336
337 /*-----------------------------------------------------------------*/
338 /* convilong - converts int or long mults or divs to fcalls        */
339 /*-----------------------------------------------------------------*/
340 static void 
341 convilong (iCode * ic, eBBlock * ebp, sym_link * type, int op)
342 {
343   symbol *func = NULL;
344   iCode *ip = ic->next;
345   iCode *newic;
346   int lineno = ic->lineno;
347   int bwd;
348   int su;
349   int bytesPushed=0;
350
351   // Easy special case which avoids function call: modulo by a literal power 
352   // of two can be replaced by a bitwise AND.
353   if (op == '%' && isOperandLiteral(IC_RIGHT(ic)))
354   {
355       unsigned litVal = (unsigned)(operandLitValue(IC_RIGHT(ic)));
356       
357       // See if literal value is a power of 2.
358       while (litVal && !(litVal & 1))
359       {
360           litVal >>= 1;
361       }
362       if (litVal)
363       {
364           // discard first high bit set.
365           litVal >>= 1;
366       }
367           
368       if (!litVal)
369       {
370           ic->op = BITWISEAND;
371           IC_RIGHT(ic) = operandFromLit(operandLitValue(IC_RIGHT(ic)) - 1);
372           return;
373       }
374   }
375     
376   remiCodeFromeBBlock (ebp, ic);    
377     
378     
379   /* depending on the type */
380   for (bwd = 0; bwd < 3; bwd++)
381     {
382       for (su = 0; su < 2; su++)
383         {
384           if (compareType (type, __multypes[bwd][su]) == 1)
385             {
386               if (op == '*')
387                 func = __muldiv[0][bwd][su];
388               else if (op == '/')
389                 func = __muldiv[1][bwd][su];
390               else if (op == '%')
391                 func = __muldiv[2][bwd][su];
392               else if (op == RRC)
393                 func = __rlrr[1][bwd][su];
394               else if (op == RLC)
395                 func = __rlrr[0][bwd][su];
396               else if (op == RIGHT_OP)
397                 func = __rlrr[1][bwd][su];
398               else if (op == LEFT_OP)
399                 func = __rlrr[0][bwd][su];
400               else
401                 assert (0);
402               goto found;
403             }
404         }
405     }
406   assert (0);
407 found:
408   /* if int & long support routines NOT compiled as reentrant */
409   if (!options.intlong_rent)
410     {
411       /* first one */
412         if (IS_REGPARM (FUNC_ARGS(func->type)->etype)) {
413             newic = newiCode (SEND, IC_LEFT (ic), NULL);
414             newic->argreg = SPEC_ARGREG(FUNC_ARGS(func->type)->etype);
415         }
416       else
417         {
418           newic = newiCode ('=', NULL, IC_LEFT (ic));
419           IC_RESULT (newic) = operandFromValue (FUNC_ARGS(func->type));
420         }
421       addiCodeToeBBlock (ebp, newic, ip);
422       newic->lineno = lineno;
423
424       /* second one */
425       if (IS_REGPARM (FUNC_ARGS(func->type)->next->etype)) {
426           newic = newiCode (SEND, IC_RIGHT (ic), NULL);
427           newic->argreg = SPEC_ARGREG(FUNC_ARGS(func->type)->next->etype);
428       }
429       else
430         {
431           newic = newiCode ('=', NULL, IC_RIGHT (ic));
432           IC_RESULT (newic) = operandFromValue (FUNC_ARGS(func->type)->next);
433         }
434       addiCodeToeBBlock (ebp, newic, ip);
435       newic->lineno = lineno;
436
437     }
438   else
439     {
440       /* compiled as reentrant then push */
441       /* push right */
442       if (IS_REGPARM (FUNC_ARGS(func->type)->next->etype))
443         {
444           newic = newiCode (SEND, IC_RIGHT (ic), NULL);
445           newic->argreg = SPEC_ARGREG(FUNC_ARGS(func->type)->next->etype);
446         }
447       else
448         {
449           newic = newiCode (IPUSH, IC_RIGHT (ic), NULL);
450           newic->parmPush = 1;
451
452           bytesPushed += getSize(operandType(IC_RIGHT(ic)));
453         }
454       addiCodeToeBBlock (ebp, newic, ip);
455       newic->lineno = lineno;
456
457       /* insert push left */
458       if (IS_REGPARM (FUNC_ARGS(func->type)->etype))
459         {
460           newic = newiCode (SEND, IC_LEFT (ic), NULL);
461           newic->argreg = SPEC_ARGREG(FUNC_ARGS(func->type)->etype);
462         }
463       else
464         {
465           newic = newiCode (IPUSH, IC_LEFT (ic), NULL);
466           newic->parmPush = 1;
467
468           bytesPushed += getSize(operandType(IC_LEFT(ic)));
469         }
470       addiCodeToeBBlock (ebp, newic, ip);
471       newic->lineno = lineno;
472
473     }
474
475   /* for the result */
476   newic = newiCode (CALL, operandFromSymbol (func), NULL);
477   IC_RESULT (newic) = IC_RESULT (ic);
478   newic->lineno = lineno;
479   newic->parmBytes+=bytesPushed; // to clear the stack after the call
480   addiCodeToeBBlock (ebp, newic, ip);
481 }
482
483 /*-----------------------------------------------------------------*/
484 /* convertToFcall - converts some operations to fcalls             */
485 /*-----------------------------------------------------------------*/
486 static void 
487 convertToFcall (eBBlock ** ebbs, int count)
488 {
489   int i;
490
491   /* for all blocks do */
492   for (i = 0; i < count; i++)
493     {
494       iCode *ic;
495
496       /* for all instructions in the block do */
497       for (ic = ebbs[i]->sch; ic; ic = ic->next)
498         {
499
500           /* floating point operations are
501              converted to function calls */
502           if ((IS_CONDITIONAL (ic) ||
503                IS_ARITHMETIC_OP (ic)) &&
504               (IS_FLOAT (operandType (IC_RIGHT (ic)))))
505             {
506
507               cnvToFcall (ic, ebbs[i]);
508             }
509
510           /* casting is a little different */
511           if (ic->op == CAST)
512             {
513               if (IS_FLOAT (operandType (IC_RIGHT (ic))))
514                 cnvFromFloatCast (ic, ebbs[i]);
515               else if (IS_FLOAT (operandType (IC_LEFT (ic))))
516                 cnvToFloatCast (ic, ebbs[i]);
517             }
518
519           /* if long / int mult or divide or mod */
520           if (ic->op == '*' || ic->op == '/' || ic->op == '%')
521             {
522               sym_link *leftType = operandType (IC_LEFT (ic));
523
524               if (IS_INTEGRAL (leftType) && getSize (leftType) > port->support.muldiv)
525                 {
526                   sym_link *rightType = operandType (IC_RIGHT (ic));
527
528                   if (port->hasNativeMulFor != NULL &&
529                       port->hasNativeMulFor (ic, leftType, rightType))
530                     {
531                       /* Leave as native */
532                     }
533                   else
534                     {
535                       convilong (ic, ebbs[i], leftType, ic->op);
536                     }
537                 }
538             }
539           
540           if (ic->op == RRC || ic->op == RLC || ic->op == LEFT_OP || ic->op == RIGHT_OP)
541             {
542               sym_link *type = operandType (IC_LEFT (ic));
543
544               if (IS_INTEGRAL (type) && getSize (type) > port->support.shift && port->support.shift >= 0)
545                 {
546                   convilong (ic, ebbs[i], type, ic->op);
547                 }
548             }
549         }
550     }
551 }
552
553 /*-----------------------------------------------------------------*/
554 /* replaceRegEqv - replace all local variables with their reqv     */
555 /*-----------------------------------------------------------------*/
556 static void 
557 replaceRegEqv (eBBlock ** ebbs, int count)
558 {
559   int i;
560
561   for (i = 0; i < count; i++)
562     {
563
564       iCode *ic;
565
566       for (ic = ebbs[i]->sch; ic; ic = ic->next)
567         {
568
569           if (SKIP_IC2 (ic))
570             continue;
571
572           if (ic->op == IFX)
573             {
574
575               if (IS_TRUE_SYMOP (IC_COND (ic)) &&
576                   OP_REQV (IC_COND (ic)))
577                 IC_COND (ic) = opFromOpWithDU (OP_REQV (IC_COND (ic)),
578                                              OP_SYMBOL (IC_COND (ic))->defs,
579                                             OP_SYMBOL (IC_COND (ic))->uses);
580
581               continue;
582             }
583
584           if (ic->op == JUMPTABLE)
585             {
586               if (IS_TRUE_SYMOP (IC_JTCOND (ic)) &&
587                   OP_REQV (IC_JTCOND (ic)))
588                 IC_JTCOND (ic) = opFromOpWithDU (OP_REQV (IC_JTCOND (ic)),
589                                            OP_SYMBOL (IC_JTCOND (ic))->defs,
590                                           OP_SYMBOL (IC_JTCOND (ic))->uses);
591               continue;
592             }
593
594           if (ic->op == RECEIVE)
595             {
596               if (OP_SYMBOL (IC_RESULT (ic))->addrtaken)
597                 OP_SYMBOL (IC_RESULT (ic))->isspilt = 1;
598             }
599
600           /* general case */
601           if (IC_RESULT (ic) &&
602               IS_TRUE_SYMOP (IC_RESULT (ic)) &&
603               OP_REQV (IC_RESULT (ic)))
604             {
605               if (POINTER_SET (ic))
606                 {
607                   IC_RESULT (ic) = opFromOpWithDU (OP_REQV (IC_RESULT (ic)),
608                                            OP_SYMBOL (IC_RESULT (ic))->defs,
609                                           OP_SYMBOL (IC_RESULT (ic))->uses);
610                   IC_RESULT (ic)->isaddr = 1;
611                 }
612               else
613                 IC_RESULT (ic) = opFromOpWithDU (OP_REQV (IC_RESULT (ic)),
614                                            OP_SYMBOL (IC_RESULT (ic))->defs,
615                                           OP_SYMBOL (IC_RESULT (ic))->uses);
616             }
617
618           if (IC_RIGHT (ic) &&
619               IS_TRUE_SYMOP (IC_RIGHT (ic)) &&
620               OP_REQV (IC_RIGHT (ic)))
621             {
622               IC_RIGHT (ic) = opFromOpWithDU (OP_REQV (IC_RIGHT (ic)),
623                                             OP_SYMBOL (IC_RIGHT (ic))->defs,
624                                            OP_SYMBOL (IC_RIGHT (ic))->uses);
625               IC_RIGHT (ic)->isaddr = 0;
626             }
627
628           if (IC_LEFT (ic) &&
629               IS_TRUE_SYMOP (IC_LEFT (ic)) &&
630               OP_REQV (IC_LEFT (ic)))
631             {
632               IC_LEFT (ic) = opFromOpWithDU (OP_REQV (IC_LEFT (ic)),
633                                              OP_SYMBOL (IC_LEFT (ic))->defs,
634                                              OP_SYMBOL (IC_LEFT (ic))->uses);
635               IC_LEFT (ic)->isaddr = 0;
636             }
637         }
638     }
639 }
640
641 /*-----------------------------------------------------------------*/
642 /* killDeadCode - eliminates dead assignments                      */
643 /*-----------------------------------------------------------------*/
644 int 
645 killDeadCode (eBBlock ** ebbs, int count)
646 {
647   int change = 1;
648   int gchange = 0;
649   int i = 0;
650
651
652   /* basic algorithm :-                                          */
653   /* first the exclusion rules :-                                */
654   /*  1. if result is a global or volatile then skip             */
655   /*  2. if assignment and result is a temp & isaddr  then skip  */
656   /*     since this means array & pointer access, will be taken  */
657   /*     care of by alias analysis.                              */
658   /*  3. if the result is used in the remainder of the block skip */
659   /*  4. if this definition does not reach the end of the block  */
660   /*     i.e. the result is not present in the outExprs then KILL */
661   /*  5. if it reaches the end of block & is used by some success */
662   /*     or then skip                                            */
663   /*     else            KILL                                    */
664   /* this whole process is carried on iteratively till no change */
665   while (1)
666     {
667
668       change = 0;
669       /* for all blocks do */
670       for (i = 0; i < count; i++)
671         {
672           iCode *ic;
673
674           /* for all instructions in the block do */
675           for (ic = ebbs[i]->sch; ic; ic = ic->next)
676             {
677               int kill, j;
678               kill = 0;
679
680               if (SKIP_IC (ic) ||
681                   ic->op == IFX ||
682                   ic->op == RETURN ||
683                   ic->op == DUMMY_READ_VOLATILE ||
684                   ic->op == CRITICAL ||
685                   ic->op == ENDCRITICAL)
686                 continue;
687
688               /* if the result is volatile then continue */
689               if (IC_RESULT (ic) && isOperandVolatile (IC_RESULT (ic), FALSE))
690                 continue;
691
692               /* if the result is a temp & isaddr then skip */
693               if (IC_RESULT (ic) && POINTER_SET (ic))
694                 continue;
695               
696               if (POINTER_GET (ic) && IS_VOLATILE (operandType (IC_LEFT (ic))->next))
697                 continue;
698
699               /* if the result is used in the remainder of the */
700               /* block then skip */
701               if (usedInRemaining (IC_RESULT (ic), ic->next))
702                 continue;
703
704               /* does this definition reach the end of the block 
705                  or the usage is zero then we can kill */
706               if (!bitVectBitValue (ebbs[i]->outDefs, ic->key))
707                 kill = 1;       /* if not we can kill it */
708               else
709                 {
710                   /* if this is a global variable or function parameter */
711                   /* we cannot kill anyway             */
712                   if (isOperandGlobal (IC_RESULT (ic)) ||
713                       (OP_SYMBOL (IC_RESULT (ic))->_isparm &&
714                        !OP_SYMBOL (IC_RESULT (ic))->ismyparm))
715                     continue;
716
717                   /* if we are sure there are no usages */
718                   if (bitVectIsZero (OP_USES (IC_RESULT (ic))))
719                     {
720                       kill = 1;
721                       goto kill;
722                     }
723
724                   /* reset visited flag */
725                   for (j = 0; j < count; ebbs[j++]->visited = 0);
726
727                   /* find out if this definition is alive */
728                   if (applyToSet (ebbs[i]->succList,
729                                   isDefAlive,
730                                   ic))
731                     continue;
732
733                   kill = 1;
734                 }
735
736             kill:
737               /* kill this one if required */
738               if (kill)
739                 {
740                   change = 1;
741                   gchange++;
742                   /* eliminate this */
743                   remiCodeFromeBBlock (ebbs[i], ic);
744
745                   /* now delete from defUseSet */
746                   deleteItemIf (&ebbs[i]->outExprs, ifDiCodeIsX, ic);
747                   bitVectUnSetBit (ebbs[i]->outDefs, ic->key);
748
749                   /* and defset of the block */
750                   bitVectUnSetBit (ebbs[i]->defSet, ic->key);
751
752                   /* for the left & right remove the usage */
753                   if (IS_SYMOP (IC_LEFT (ic)))
754                     bitVectUnSetBit (OP_USES (IC_LEFT (ic)), ic->key);
755
756                   if (IS_SYMOP (IC_RIGHT (ic)))
757                     bitVectUnSetBit (OP_USES (IC_RIGHT (ic)), ic->key);
758                 }
759
760             }                   /* end of all instructions */
761
762           if (!ebbs[i]->sch && !ebbs[i]->noPath)
763             disconBBlock (ebbs[i], ebbs, count);
764
765         }                       /* end of for all blocks */
766
767       if (!change)
768         break;
769     }                           /* end of while(1) */
770
771   return gchange;
772 }
773
774 /*-----------------------------------------------------------------*/
775 /* printCyclomatic - prints the cyclomatic information             */
776 /*-----------------------------------------------------------------*/
777 static void 
778 printCyclomatic (eBBlock ** ebbs, int count)
779 {
780   int nEdges = elementsInSet (graphEdges);
781   int i, nNodes = 0;
782
783   for (i = 0; i < count; i++)
784     nNodes += (!ebbs[i]->noPath);
785
786   /* print the information */
787   werror (I_CYCLOMATIC, currFunc->name, nEdges, nNodes, nEdges - nNodes + 2);
788 }
789
790 /*-----------------------------------------------------------------*/
791 /* discardDeadParamReceives - remove any RECEIVE opcodes which     */
792 /* refer to dead variables.                                        */
793 /*-----------------------------------------------------------------*/
794 static void 
795 discardDeadParamReceives (eBBlock ** ebbs, int count)
796 {
797   int i;
798   iCode *ic;
799   iCode dummyIcode;
800
801   for (i = 0; i < count; i++)
802     {
803       for (ic = ebbs[i]->sch; ic; ic = ic->next)
804         {
805           if (ic->op == RECEIVE)
806             {
807               if (IC_RESULT (ic) && OP_SYMBOL (IC_RESULT (ic))
808                   && !OP_SYMBOL (IC_RESULT (ic))->used)
809                 {
810 #if 0
811                   fprintf (stderr, "discarding dead receive for %s\n",
812                            OP_SYMBOL (IC_RESULT (ic))->name);
813 #endif
814                   dummyIcode.next = ic->next;
815                   remiCodeFromeBBlock (ebbs[i], ic);
816                   ic = &dummyIcode;
817                 }
818             }
819         }
820     }
821 }
822
823 /*-----------------------------------------------------------------*/
824 /* eBBlockFromiCode - creates extended basic blocks from iCode     */
825 /*                    will return an array of eBBlock pointers     */
826 /*-----------------------------------------------------------------*/
827 eBBlock **
828 eBBlockFromiCode (iCode * ic)
829 {
830   eBBlock **ebbs = NULL;
831   int count = 0;
832   int saveCount = 0;
833   int change = 1;
834   int lchange = 0;
835   int kchange = 0;
836   hTab *loops;
837
838   /* if nothing passed then return nothing */
839   if (!ic)
840     return NULL;
841
842   count = 0;
843   eBBNum = 0;
844
845   /* optimize the chain for labels & gotos 
846      this will eliminate redundant labels and
847      will change jump to jumps by jumps */
848   ic = iCodeLabelOptimize (ic);
849
850   /* break it down into basic blocks */
851   ebbs = iCodeBreakDown (ic, &count);
852   saveCount = count;
853
854   /* compute the control flow */
855   computeControlFlow (ebbs, count, 0);
856
857   /* dumpraw if asked for */
858   if (options.dump_raw)
859     dumpEbbsToFileExt (DUMP_RAW0, ebbs, count);
860
861   /* replace the local variables with their
862      register equivalents : the liveRange computation
863      along with the register allocation will determine
864      if it finally stays in the registers */
865   replaceRegEqv (ebbs, count);
866
867   /* create loop regions */
868   loops = createLoopRegions (ebbs, count);
869
870   /* dumpraw if asked for */
871   if (options.dump_raw)
872     dumpEbbsToFileExt (DUMP_RAW1, ebbs, count);
873
874   /* do common subexpression elimination for each block */
875   change = cseAllBlocks (ebbs, saveCount, FALSE);
876
877   /* dumpraw if asked for */
878   if (options.dump_raw)
879     dumpEbbsToFileExt (DUMP_CSE, ebbs, count);
880
881   /* compute the data flow */
882   computeDataFlow (ebbs, saveCount);
883
884   /* dumpraw if asked for */
885   if (options.dump_raw)
886     dumpEbbsToFileExt (DUMP_DFLOW, ebbs, count);
887
888   /* global common subexpression elimination  */
889   if (optimize.global_cse)
890     {
891       change += cseAllBlocks (ebbs, saveCount, FALSE);
892       if (options.dump_gcse)
893         dumpEbbsToFileExt (DUMP_GCSE, ebbs, saveCount);
894     }
895   else
896     {
897       // compute the dataflow only
898       assert(cseAllBlocks (ebbs, saveCount, TRUE)==0);
899     }
900   /* kill dead code */
901   kchange = killDeadCode (ebbs, saveCount);
902
903   if (options.dump_kill)
904     dumpEbbsToFileExt (DUMP_DEADCODE, ebbs, count);
905
906   /* do loop optimizations */
907   change += (lchange = loopOptimizations (loops, ebbs, count));
908   if (options.dump_loop)
909     dumpEbbsToFileExt (DUMP_LOOP, ebbs, count);
910
911   /* recompute the data flow and apply global cse again 
912      if loops optimizations or dead code caused a change:
913      loops will brings out of the loop which then may be
914      available for use in the later blocks: dead code
915      elimination could potentially disconnect some blocks
916      conditional flow may be efected so we need to apply
917      subexpression once more */
918   if (lchange || kchange)
919     {
920       computeDataFlow (ebbs, saveCount);
921       change += cseAllBlocks (ebbs, saveCount, FALSE);
922       if (options.dump_loop)
923         dumpEbbsToFileExt (DUMP_LOOPG, ebbs, count);
924
925       /* if loop optimizations caused a change then do
926          dead code elimination once more : this will
927          get rid of the extra assignments to the induction
928          variables created during loop optimizations */
929       killDeadCode (ebbs, saveCount);
930
931       if (options.dump_loop)
932         dumpEbbsToFileExt (DUMP_LOOPD, ebbs, count);
933
934     }
935
936   /* sort it back by block number */
937   qsort (ebbs, saveCount, sizeof (eBBlock *), bbNumCompare);
938
939   if (!options.lessPedantic) {
940     // this is a good place to check missing return values
941     if (currFunc) {
942       // the user is on his own with naked functions...
943       if (!IS_VOID(currFunc->etype)
944        && !FUNC_ISNAKED(currFunc->type)) {
945         eBBlock *bp;
946         // make sure all predecessors of the last block end in a return
947         for (bp=setFirstItem(ebbs[saveCount-1]->predList); 
948              bp; 
949              bp=setNextItem(ebbs[saveCount-1]->predList)) {
950           if (bp->ech->op != RETURN) {
951             werror (W_VOID_FUNC, currFunc->name);
952           }
953         }
954       }
955     }
956   }
957
958   /* if cyclomatic info requested then print it */
959   if (options.cyclomatic)
960     printCyclomatic (ebbs, saveCount);
961
962   /* convert operations with support routines
963      written in C to function calls : Iam doing
964      this at this point since I want all the
965      operations to be as they are for optimzations */
966   convertToFcall (ebbs, count);
967
968   /* compute the live ranges */
969   computeLiveRanges (ebbs, count);
970
971   if (options.dump_range)
972     dumpEbbsToFileExt (DUMP_RANGE, ebbs, count);
973
974   /* Now that we have the live ranges, discard parameter
975    * receives for unused parameters.
976    */
977   discardDeadParamReceives (ebbs, count);
978
979   /* allocate registers & generate code */
980   port->assignRegisters (ebbs, count);
981
982   /* throw away blocks */
983   setToNull ((void *) &graphEdges);
984   ebbs = NULL;
985   
986   return NULL;
987 }
988
989
990 /* (add-hook 'c-mode-hook (lambda () (setq c-basic-offset 4))) */