Use 'ao-dbg' instead of 's51' to communicate with TeleMetrum
[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 <math.h>
30 #include "common.h"
31
32 /*-----------------------------------------------------------------*/
33 /* global variables */
34 int cseDefNum = 0;
35
36 char flowChanged = 0;
37
38
39 /*-----------------------------------------------------------------*/
40 /* printSymName - prints the symbol names                          */
41 /*-----------------------------------------------------------------*/
42 int
43 printSymName (void *vsym)
44 {
45   symbol *sym = vsym;
46   fprintf (stdout, " %s ", sym->name);
47   return 0;
48 }
49
50 /*-----------------------------------------------------------------*/
51 /* cnvToFcall - does the actual conversion to function call        */
52 /*-----------------------------------------------------------------*/
53 static void
54 cnvToFcall (iCode * ic, eBBlock * ebp)
55 {
56   iCode *ip;
57   iCode *newic;
58   operand *left;
59   operand *right;
60   symbol *func = NULL;
61   char *filename = ic->filename;
62   int lineno = ic->lineno;
63   int bytesPushed=0;
64
65   ip = ic->next;                /* insertion point */
66   /* remove it from the iCode */
67   remiCodeFromeBBlock (ebp, ic);
68
69   left = IC_LEFT (ic);
70   right = IC_RIGHT (ic);
71
72   if (IS_SYMOP (left))
73       bitVectUnSetBit (OP_USES (left), ic->key);
74   if (IS_SYMOP (right))
75       bitVectUnSetBit (OP_USES (right), ic->key);
76
77   if (IS_FLOAT (operandType (right))) {
78     switch (ic->op)
79       {
80       case '+':
81         func = __fsadd;
82         break;
83       case '-':
84         func = __fssub;
85         break;
86       case '/':
87         func = __fsdiv;
88         break;
89       case '*':
90         func = __fsmul;
91         break;
92       case EQ_OP:
93         func = __fseq;
94         break;
95       case NE_OP:
96         func = __fsneq;
97         break;
98       case '<':
99         func = __fslt;
100         break;
101       case '>':
102         func = __fsgt;
103         break;
104       case LE_OP:
105         func = __fslteq;
106         break;
107       case GE_OP:
108         func = __fsgteq;
109         break;
110       }
111   } else
112   if (IS_FIXED16X16 (operandType (right))) {
113     switch (ic->op)
114       {
115       case '+':
116         func = __fps16x16_add;
117         break;
118       case '-':
119         func = __fps16x16_sub;
120         break;
121       case '/':
122         func = __fps16x16_div;
123         break;
124       case '*':
125         func = __fps16x16_mul;
126         break;
127       case EQ_OP:
128         func = __fps16x16_eq;
129         break;
130       case NE_OP:
131         func = __fps16x16_neq;
132         break;
133       case '<':
134         func = __fps16x16_lt;
135         break;
136       case '>':
137         func = __fps16x16_gt;
138         break;
139       case LE_OP:
140         func = __fps16x16_lteq;
141         break;
142       case GE_OP:
143         func = __fps16x16_gteq;
144         break;
145       }
146   }
147
148
149   /* if float support routines NOT compiled as reentrant */
150   if (!options.float_rent)
151     {
152
153       /* first one */
154       if (IS_REGPARM (FUNC_ARGS(func->type)->etype))
155         {
156           newic = newiCode (SEND, left, NULL);
157           newic->argreg = SPEC_ARGREG(FUNC_ARGS(func->type)->etype);
158         }
159       else
160         {
161           newic = newiCode ('=', NULL, left);
162           IC_RESULT (newic) = operandFromValue (FUNC_ARGS(func->type));
163         }
164
165       addiCodeToeBBlock (ebp, newic, ip);
166       newic->filename = filename;
167       newic->lineno = lineno;
168       if (IS_SYMOP (left))
169           OP_USES (left) = bitVectSetBit (OP_USES (left), newic->key);
170
171       /* second one */
172       if (IS_REGPARM (FUNC_ARGS(func->type)->next->etype))
173         {
174           newic = newiCode (SEND, right, NULL);
175           newic->argreg = SPEC_ARGREG(FUNC_ARGS(func->type)->next->etype);
176         }
177       else
178         {
179           newic = newiCode ('=', NULL, right);
180           IC_RESULT (newic) = operandFromValue (FUNC_ARGS(func->type)->next);
181         }
182       addiCodeToeBBlock (ebp, newic, ip);
183       newic->filename = filename;
184       newic->lineno = lineno;
185       if (IS_SYMOP (right))
186           OP_USES (right) = bitVectSetBit (OP_USES (right), newic->key);
187
188     }
189   else
190     {
191
192       /* push right */
193       if (IS_REGPARM (FUNC_ARGS(func->type)->next->etype))
194         {
195           newic = newiCode (SEND, right, NULL);
196           newic->argreg = SPEC_ARGREG(FUNC_ARGS(func->type)->next->etype);
197         }
198       else
199         {
200           newic = newiCode (IPUSH, right, NULL);
201           newic->parmPush = 1;
202           bytesPushed += getSize(operandType(right));
203         }
204
205       addiCodeToeBBlock (ebp, newic, ip);
206       newic->filename = filename;
207       newic->lineno = lineno;
208       if (IS_SYMOP (right))
209           OP_USES (right) = bitVectSetBit (OP_USES (right), newic->key);
210
211       /* insert push left */
212       if (IS_REGPARM (FUNC_ARGS(func->type)->etype))
213         {
214           newic = newiCode (SEND, left, NULL);
215           newic->argreg = SPEC_ARGREG(FUNC_ARGS(func->type)->etype);
216         }
217       else
218         {
219           newic = newiCode (IPUSH, left, NULL);
220           newic->parmPush = 1;
221           bytesPushed += getSize(operandType(left));
222         }
223       addiCodeToeBBlock (ebp, newic, ip);
224       newic->filename = filename;
225       newic->lineno = lineno;
226       if (IS_SYMOP (left))
227           OP_USES (left) = bitVectSetBit (OP_USES (left), newic->key);
228
229     }
230   /* insert the call */
231   newic = newiCode (CALL, operandFromSymbol (func), NULL);
232   IC_RESULT (newic) = IC_RESULT (ic);
233   bitVectUnSetBit (OP_DEFS (IC_RESULT (ic)), ic->key);
234   OP_USES (IC_RESULT (newic)) = bitVectSetBit (OP_USES (IC_RESULT (newic)), newic->key);
235   newic->filename = filename;
236   newic->lineno = lineno;
237   newic->parmBytes += bytesPushed;
238   ebp->hasFcall = 1;
239   if (currFunc)
240     FUNC_HASFCALL (currFunc->type) = 1;
241
242   if(TARGET_IS_PIC16 || TARGET_IS_PIC) {
243         /* normally these functions aren't marked external, so we can use their
244          * _extern field to marked as already added to symbol table */
245
246         if(!SPEC_EXTR(func->etype)) {
247             memmap *seg = SPEC_OCLS(OP_SYMBOL(IC_LEFT(newic))->etype);
248
249             SPEC_EXTR(func->etype) = 1;
250             seg = SPEC_OCLS( func->etype );
251             addSet(&seg->syms, func);
252         }
253   }
254
255   addiCodeToeBBlock (ebp, newic, ip);
256 }
257
258 /*-----------------------------------------------------------------*/
259 /* cnvToFloatCast - converts casts to floats to function calls     */
260 /*-----------------------------------------------------------------*/
261 static void
262 cnvToFloatCast (iCode * ic, eBBlock * ebp)
263 {
264   iCode *ip, *newic;
265   symbol *func = NULL;
266   sym_link *type = operandType (IC_RIGHT (ic));
267   int linenno = 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   /* depending on the type */
275   for (bwd = 0; bwd < 3; bwd++)
276     {
277       for (su = 0; su < 2; su++)
278         {
279           if (compareType (type, __multypes[bwd][su]) == 1)
280             {
281               func = __conv[0][bwd][su];
282               goto found;
283             }
284         }
285     }
286
287   if(compareType (type, fixed16x16Type) == 1) {
288     func = __fp16x16conv[0][3][0];
289     goto found;
290   }
291
292   assert (0);
293 found:
294
295   /* if float support routines NOT compiled as reentrant */
296   if (!options.float_rent)
297     {
298       /* first one */
299       if (IS_REGPARM (FUNC_ARGS(func->type)->etype))
300         {
301           newic = newiCode (SEND, IC_RIGHT (ic), NULL);
302           newic->argreg = SPEC_ARGREG(FUNC_ARGS(func->type)->etype);
303         }
304       else
305         {
306           newic = newiCode ('=', NULL, IC_RIGHT (ic));
307           IC_RESULT (newic) = operandFromValue (FUNC_ARGS(func->type));
308         }
309       addiCodeToeBBlock (ebp, newic, ip);
310       newic->filename = filename;
311       newic->lineno = linenno;
312
313     }
314   else
315     {
316       /* push the left */
317       if (IS_REGPARM (FUNC_ARGS(func->type)->etype)) {
318         newic = newiCode (SEND, IC_RIGHT (ic), NULL);
319         newic->argreg = SPEC_ARGREG(FUNC_ARGS(func->type)->etype);
320       }
321       else
322       {
323         newic = newiCode (IPUSH, IC_RIGHT (ic), NULL);
324         newic->parmPush = 1;
325         bytesPushed += getSize(operandType(IC_RIGHT(ic)));
326       }
327       addiCodeToeBBlock (ebp, newic, ip);
328       newic->filename = filename;
329       newic->lineno = linenno;
330     }
331
332   /* make the call */
333   newic = newiCode (CALL, operandFromSymbol (func), NULL);
334   IC_RESULT (newic) = IC_RESULT (ic);
335   newic->parmBytes+=bytesPushed;
336   ebp->hasFcall = 1;
337   if (currFunc)
338     FUNC_HASFCALL (currFunc->type) = 1;
339
340   if(TARGET_IS_PIC16 || TARGET_IS_PIC) {
341         /* normally these functions aren't marked external, so we can use their
342          * _extern field to marked as already added to symbol table */
343
344         if(!SPEC_EXTR(func->etype)) {
345             memmap *seg = SPEC_OCLS(OP_SYMBOL(IC_LEFT(newic))->etype);
346
347             SPEC_EXTR(func->etype) = 1;
348             seg = SPEC_OCLS( func->etype );
349             addSet(&seg->syms, func);
350         }
351   }
352
353   addiCodeToeBBlock (ebp, newic, ip);
354   newic->filename = filename;
355   newic->lineno = linenno;
356 }
357
358 /*----------------------------------------------------------------------*/
359 /* cnvToFixed16x16Cast - converts casts to fixed16x16 to function calls */
360 /*----------------------------------------------------------------------*/
361 static void
362 cnvToFixed16x16Cast (iCode * ic, eBBlock * ebp)
363 {
364   iCode *ip, *newic;
365   symbol *func = NULL;
366   sym_link *type = operandType (IC_RIGHT (ic));
367   int linenno = ic->lineno;
368   int bwd, su;
369   int bytesPushed=0;
370
371   ip = ic->next;
372   /* remove it from the iCode */
373   remiCodeFromeBBlock (ebp, ic);
374   /* depending on the type */
375   for (bwd = 0; bwd < 3; bwd++)
376     {
377       for (su = 0; su < 2; su++)
378         {
379           if (compareType (type, __multypes[bwd][su]) == 1)
380             {
381               func = __fp16x16conv[0][bwd][su];
382               goto found;
383             }
384         }
385     }
386   assert (0);
387 found:
388
389   /* if float support routines NOT compiled as reentrant */
390   if (!options.float_rent)
391     {
392       /* first one */
393         if (IS_REGPARM (FUNC_ARGS(func->type)->etype))
394             {
395                 newic = newiCode (SEND, IC_RIGHT (ic), NULL);
396                 newic->argreg = SPEC_ARGREG(FUNC_ARGS(func->type)->etype);
397             }
398       else
399         {
400           newic = newiCode ('=', NULL, IC_RIGHT (ic));
401           IC_RESULT (newic) = operandFromValue (FUNC_ARGS(func->type));
402         }
403       addiCodeToeBBlock (ebp, newic, ip);
404       newic->filename = filename;
405       newic->lineno = linenno;
406
407     }
408   else
409     {
410       /* push the left */
411         if (IS_REGPARM (FUNC_ARGS(func->type)->etype)) {
412             newic = newiCode (SEND, IC_RIGHT (ic), NULL);
413             newic->argreg = SPEC_ARGREG(FUNC_ARGS(func->type)->etype);
414         }
415       else
416         {
417           newic = newiCode (IPUSH, IC_RIGHT (ic), NULL);
418           newic->parmPush = 1;
419           bytesPushed += getSize(operandType(IC_RIGHT(ic)));
420         }
421       addiCodeToeBBlock (ebp, newic, ip);
422       newic->filename = filename;
423       newic->lineno = linenno;
424     }
425
426   /* make the call */
427   newic = newiCode (CALL, operandFromSymbol (func), NULL);
428   IC_RESULT (newic) = IC_RESULT (ic);
429   newic->parmBytes+=bytesPushed;
430   ebp->hasFcall = 1;
431   if (currFunc)
432     FUNC_HASFCALL (currFunc->type) = 1;
433
434   if(TARGET_IS_PIC16 || TARGET_IS_PIC) {
435         /* normally these functions aren't marked external, so we can use their
436          * _extern field to marked as already added to symbol table */
437
438         if(!SPEC_EXTR(func->etype)) {
439             memmap *seg = SPEC_OCLS(OP_SYMBOL(IC_LEFT(newic))->etype);
440
441                 SPEC_EXTR(func->etype) = 1;
442                 seg = SPEC_OCLS( func->etype );
443                 addSet(&seg->syms, func);
444         }
445   }
446
447   addiCodeToeBBlock (ebp, newic, ip);
448   newic->filename = filename;
449   newic->lineno = linenno;
450 }
451
452 /*-----------------------------------------------------------------*/
453 /* cnvFromFloatCast - converts casts From floats to function calls */
454 /*-----------------------------------------------------------------*/
455 static void
456 cnvFromFloatCast (iCode * ic, eBBlock * ebp)
457 {
458   iCode *ip, *newic;
459   symbol *func = NULL;
460   sym_link *type = operandType (IC_LEFT (ic));
461   char *filename = ic->filename;
462   int lineno = ic->lineno;
463   int bwd, su;
464   int bytesPushed=0;
465
466   ip = ic->next;
467   /* remove it from the iCode */
468   remiCodeFromeBBlock (ebp, ic);
469
470   /* depending on the type */
471   for (bwd = 0; bwd < 3; bwd++)
472     {
473       for (su = 0; su < 2; su++)
474         {
475           if (compareType (type, __multypes[bwd][su]) == 1)
476             {
477               func = __conv[1][bwd][su];
478               goto found;
479             }
480         }
481     }
482   assert (0);
483 found:
484
485   /* if float support routines NOT compiled as reentrant */
486   if (!options.float_rent)
487     {
488       /* first one */
489         if (IS_REGPARM (FUNC_ARGS(func->type)->etype)) {
490             newic = newiCode (SEND, IC_RIGHT (ic), NULL);
491             newic->argreg = SPEC_ARGREG(FUNC_ARGS(func->type)->etype);
492         }
493       else
494         {
495           newic = newiCode ('=', NULL, IC_RIGHT (ic));
496           IC_RESULT (newic) = operandFromValue (FUNC_ARGS(func->type));
497         }
498       addiCodeToeBBlock (ebp, newic, ip);
499       newic->filename = filename;
500       newic->lineno = lineno;
501
502     }
503   else
504     {
505
506       /* push the left */
507         if (IS_REGPARM (FUNC_ARGS(func->type)->etype)) {
508             newic = newiCode (SEND, IC_RIGHT (ic), NULL);
509             newic->argreg = SPEC_ARGREG(FUNC_ARGS(func->type)->etype);
510         }
511       else
512         {
513           newic = newiCode (IPUSH, IC_RIGHT (ic), NULL);
514           newic->parmPush = 1;
515           bytesPushed += getSize(operandType(IC_RIGHT(ic)));
516         }
517       addiCodeToeBBlock (ebp, newic, ip);
518       newic->filename = filename;
519       newic->lineno = lineno;
520
521     }
522
523   /* make the call */
524   newic = newiCode (CALL, operandFromSymbol (func), NULL);
525   IC_RESULT (newic) = IC_RESULT (ic);
526   newic->parmBytes+=bytesPushed;
527   ebp->hasFcall = 1;
528   if (currFunc)
529     FUNC_HASFCALL (currFunc->type) = 1;
530
531   if(TARGET_IS_PIC16 || TARGET_IS_PIC) {
532         /* normally these functions aren't marked external, so we can use their
533          * _extern field to marked as already added to symbol table */
534
535         if(!SPEC_EXTR(func->etype)) {
536             memmap *seg = SPEC_OCLS(OP_SYMBOL(IC_LEFT(newic))->etype);
537
538                 SPEC_EXTR(func->etype) = 1;
539                 seg = SPEC_OCLS( func->etype );
540                 addSet(&seg->syms, func);
541         }
542   }
543
544   addiCodeToeBBlock (ebp, newic, ip);
545   newic->filename = filename;
546   newic->lineno = lineno;
547 }
548
549 /*--------------------------------------------------------------------------*/
550 /* cnvFromFixed16x16Cast - converts casts from fixed16x16 to function calls */
551 /*--------------------------------------------------------------------------*/
552 static void
553 cnvFromFixed16x16Cast (iCode * ic, eBBlock * ebp)
554 {
555   iCode *ip, *newic;
556   symbol *func = NULL;
557   sym_link *type = operandType (IC_LEFT (ic));
558   char *filename = ic->filename;
559   int lineno = ic->lineno;
560   int bwd, su;
561   int bytesPushed=0;
562
563   ip = ic->next;
564   /* remove it from the iCode */
565   remiCodeFromeBBlock (ebp, ic);
566
567   /* depending on the type */
568   for (bwd = 0; bwd < 3; bwd++)
569     {
570       for (su = 0; su < 2; su++)
571         {
572           if (compareType (type, __multypes[bwd][su]) == 1)
573             {
574               func = __fp16x16conv[1][bwd][su];
575               goto found;
576             }
577         }
578     }
579
580   if (compareType (type, floatType) == 1)
581     {
582       func = __fp16x16conv[1][3][0];
583       goto found;
584     }
585
586   assert (0);
587 found:
588
589   /* if float support routines NOT compiled as reentrant */
590   if (!options.float_rent)
591     {
592       /* first one */
593         if (IS_REGPARM (FUNC_ARGS(func->type)->etype)) {
594             newic = newiCode (SEND, IC_RIGHT (ic), NULL);
595             newic->argreg = SPEC_ARGREG(FUNC_ARGS(func->type)->etype);
596         }
597       else
598         {
599           newic = newiCode ('=', NULL, IC_RIGHT (ic));
600           IC_RESULT (newic) = operandFromValue (FUNC_ARGS(func->type));
601         }
602       addiCodeToeBBlock (ebp, newic, ip);
603       newic->filename = filename;
604       newic->lineno = lineno;
605     }
606   else
607     {
608
609       /* push the left */
610         if (IS_REGPARM (FUNC_ARGS(func->type)->etype)) {
611             newic = newiCode (SEND, IC_RIGHT (ic), NULL);
612             newic->argreg = SPEC_ARGREG(FUNC_ARGS(func->type)->etype);
613         }
614       else
615         {
616           newic = newiCode (IPUSH, IC_RIGHT (ic), NULL);
617           newic->parmPush = 1;
618           bytesPushed += getSize(operandType(IC_RIGHT(ic)));
619         }
620       addiCodeToeBBlock (ebp, newic, ip);
621       newic->filename = filename;
622       newic->lineno = lineno;
623     }
624
625   /* make the call */
626   newic = newiCode (CALL, operandFromSymbol (func), NULL);
627   IC_RESULT (newic) = IC_RESULT (ic);
628   newic->parmBytes+=bytesPushed;
629   ebp->hasFcall = 1;
630   if (currFunc)
631     FUNC_HASFCALL (currFunc->type) = 1;
632
633   if(TARGET_IS_PIC16 || TARGET_IS_PIC) {
634         /* normally these functions aren't marked external, so we can use their
635          * _extern field to marked as already added to symbol table */
636
637         if(!SPEC_EXTR(func->etype)) {
638             memmap *seg = SPEC_OCLS(OP_SYMBOL(IC_LEFT(newic))->etype);
639
640                 SPEC_EXTR(func->etype) = 1;
641                 seg = SPEC_OCLS( func->etype );
642                 addSet(&seg->syms, func);
643         }
644   }
645
646   addiCodeToeBBlock (ebp, newic, ip);
647   newic->filename = filename;
648   newic->lineno = lineno;
649 }
650
651 extern operand *geniCodeRValue (operand *, bool);
652
653 /*-----------------------------------------------------------------*/
654 /* convilong - converts int or long mults or divs to fcalls        */
655 /*-----------------------------------------------------------------*/
656 static void
657 convilong (iCode * ic, eBBlock * ebp)
658 {
659   int op = ic->op;
660   symbol *func = NULL;
661   iCode *ip = ic->next;
662   iCode *newic;
663   char *filename = ic->filename;
664   int lineno = ic->lineno;
665   int bwd;
666   int su;
667   int bytesPushed=0;
668   sym_link *leftType = operandType (IC_LEFT (ic));
669   sym_link *rightType = operandType (IC_RIGHT (ic));
670
671   remiCodeFromeBBlock (ebp, ic);
672
673   if (getSize (leftType) == 1 && getSize (rightType) == 1)
674     {
675       int muldivmod;
676
677       if (op == '*')
678         muldivmod = 0;
679       else if (op == '/')
680         muldivmod = 1;
681       else if (op == '%')
682         muldivmod = 2;
683       else
684         muldivmod = -1;
685
686       for (su = 0; su < 4 && muldivmod >= 0; su++)
687         {
688           if ((compareType (leftType, __multypes[0][su%2]) == 1) &&
689               (compareType (rightType, __multypes[0][su/2]) == 1))
690             {
691               func = __muldiv[muldivmod][0][su];
692               goto found;
693             }
694         }
695     }
696
697   /* depending on the type */
698   for (bwd = 0; bwd < 3; bwd++)
699     {
700       for (su = 0; su < 2; su++)
701         {
702           if (compareType (leftType, __multypes[bwd][su]) == 1)
703             {
704               if ((op=='*' || op=='/' || op=='%') &&
705                   compareType (rightType, __multypes[bwd][su]) != 1)
706                 {
707                   assert(0);
708                 }
709
710               if (op == '*')
711                 func = __muldiv[0][bwd][su];
712               else if (op == '/')
713                 func = __muldiv[1][bwd][su];
714               else if (op == '%')
715                 func = __muldiv[2][bwd][su];
716               else if (op == RRC)
717                 func = __rlrr[1][bwd][su];
718               else if (op == RLC)
719                 func = __rlrr[0][bwd][su];
720               else if (op == RIGHT_OP)
721                 func = __rlrr[1][bwd][su];
722               else if (op == LEFT_OP)
723                 func = __rlrr[0][bwd][su];
724               else
725                 assert (0);
726               goto found;
727             }
728         }
729     }
730   assert (0);
731 found:
732   /* if int & long support routines NOT compiled as reentrant */
733   if (!options.intlong_rent)
734     {
735       /* first one */
736         if (IS_REGPARM (FUNC_ARGS(func->type)->etype)) {
737             newic = newiCode (SEND, IC_LEFT (ic), NULL);
738             newic->argreg = SPEC_ARGREG(FUNC_ARGS(func->type)->etype);
739         }
740       else
741         {
742           newic = newiCode ('=', NULL, IC_LEFT (ic));
743           IC_RESULT (newic) = operandFromValue (FUNC_ARGS(func->type));
744         }
745       addiCodeToeBBlock (ebp, newic, ip);
746       newic->filename = filename;
747       newic->lineno = lineno;
748
749       /* second one */
750       if (IS_REGPARM (FUNC_ARGS(func->type)->next->etype)) {
751           newic = newiCode (SEND, IC_RIGHT (ic), NULL);
752           newic->argreg = SPEC_ARGREG(FUNC_ARGS(func->type)->next->etype);
753       }
754       else
755         {
756           newic = newiCode ('=', NULL, IC_RIGHT (ic));
757           IC_RESULT (newic) = operandFromValue (FUNC_ARGS(func->type)->next);
758         }
759       addiCodeToeBBlock (ebp, newic, ip);
760       newic->filename = filename;
761       newic->lineno = lineno;
762
763     }
764   else
765     {
766       /* compiled as reentrant then push */
767       /* push right */
768       if (IS_REGPARM (FUNC_ARGS(func->type)->next->etype))
769         {
770           newic = newiCode (SEND, IC_RIGHT (ic), NULL);
771           newic->argreg = SPEC_ARGREG(FUNC_ARGS(func->type)->next->etype);
772         }
773       else
774         {
775           newic = newiCode (IPUSH, IC_RIGHT (ic), NULL);
776           newic->parmPush = 1;
777
778           bytesPushed += getSize(operandType(IC_RIGHT(ic)));
779         }
780       addiCodeToeBBlock (ebp, newic, ip);
781       newic->filename = filename;
782       newic->lineno = lineno;
783
784       /* insert push left */
785       if (IS_REGPARM (FUNC_ARGS(func->type)->etype))
786         {
787           newic = newiCode (SEND, IC_LEFT (ic), NULL);
788           newic->argreg = SPEC_ARGREG(FUNC_ARGS(func->type)->etype);
789         }
790       else
791         {
792           newic = newiCode (IPUSH, IC_LEFT (ic), NULL);
793           newic->parmPush = 1;
794
795           bytesPushed += getSize(operandType(IC_LEFT(ic)));
796         }
797       addiCodeToeBBlock (ebp, newic, ip);
798       newic->filename = filename;
799       newic->lineno = lineno;
800
801     }
802
803   /* for the result */
804   newic = newiCode (CALL, operandFromSymbol (func), NULL);
805   IC_RESULT (newic) = IC_RESULT (ic);
806   newic->filename = filename;
807   newic->lineno = lineno;
808   newic->parmBytes+=bytesPushed; // to clear the stack after the call
809   ebp->hasFcall = 1;
810   if (currFunc)
811     FUNC_HASFCALL (currFunc->type) = 1;
812
813   if(TARGET_IS_PIC || TARGET_IS_PIC16) {
814         /* normally these functions aren't marked external, so we can use their
815          * _extern field to marked as already added to symbol table */
816
817         if(!SPEC_EXTR(func->etype)) {
818             memmap *seg = SPEC_OCLS(OP_SYMBOL(IC_LEFT(newic))->etype);
819
820                 SPEC_EXTR(func->etype) = 1;
821                 seg = SPEC_OCLS( func->etype );
822                 addSet(&seg->syms, func);
823         }
824   }
825
826   addiCodeToeBBlock (ebp, newic, ip);
827 }
828
829 /*-----------------------------------------------------------------*/
830 /* convertToFcall - converts some operations to fcalls             */
831 /*-----------------------------------------------------------------*/
832 static void
833 convertToFcall (eBBlock ** ebbs, int count)
834 {
835   int i;
836
837   /* for all blocks do */
838   for (i = 0; i < count; i++)
839     {
840       iCode *ic;
841
842       /* for all instructions in the block do */
843       for (ic = ebbs[i]->sch; ic; ic = ic->next)
844         {
845
846           /* floating point operations are
847              converted to function calls */
848           if ((IS_CONDITIONAL (ic) ||
849                IS_ARITHMETIC_OP (ic)) &&
850               (IS_FLOAT (operandType (IC_RIGHT (ic))) ||
851                IS_FIXED( operandType (IC_RIGHT (ic)))))
852             {
853               cnvToFcall (ic, ebbs[i]);
854             }
855
856           /* casting is a little different */
857           if (ic->op == CAST)
858             {
859               if (IS_FLOAT (operandType (IC_RIGHT (ic))))
860                 cnvFromFloatCast (ic, ebbs[i]);
861               else if (IS_FLOAT (operandType (IC_LEFT (ic))))
862                 cnvToFloatCast (ic, ebbs[i]);
863               if (IS_FIXED16X16 (operandType (IC_RIGHT (ic))))
864                 cnvFromFixed16x16Cast (ic, ebbs[i]);
865               else if (IS_FIXED16X16 (operandType (IC_LEFT (ic))))
866                 cnvToFixed16x16Cast (ic, ebbs[i]);
867             }
868
869           // Easy special case which avoids function call: modulo by a literal power
870           // of two can be replaced by a bitwise AND.
871           if (ic->op == '%' && isOperandLiteral(IC_RIGHT(ic)) &&
872               IS_UNSIGNED(operandType(IC_LEFT(ic))))
873             {
874               unsigned litVal = abs((unsigned) double2ul (operandLitValue(IC_RIGHT(ic))));
875
876               /* modulo by 1: no remainder */
877               if (litVal == 1)
878                 {
879                   ic->op = '=';
880                   IC_RIGHT (ic) = operandFromLit(0);
881                   IC_LEFT (ic) = NULL;
882                   continue;
883                 }
884               // See if literal value is a power of 2.
885               while (litVal && !(litVal & 1))
886                 {
887                   litVal >>= 1;
888                 }
889               if (litVal)
890                 {
891                   // discard lowest set bit.
892                   litVal >>= 1;
893                 }
894
895               if (!litVal)
896                 {
897                   ic->op = BITWISEAND;
898                   IC_RIGHT(ic) = operandFromLit(operandLitValue(IC_RIGHT(ic)) - 1);
899                   continue;
900                 }
901             }
902
903           /* if long / int mult or divide or mod */
904           if (ic->op == '*' || ic->op == '/' || ic->op == '%')
905             {
906               sym_link *leftType = operandType (IC_LEFT (ic));
907
908               if (IS_INTEGRAL (leftType) && getSize (leftType) > port->support.muldiv)
909                 {
910                   sym_link *rightType = operandType (IC_RIGHT (ic));
911
912                   if (port->hasNativeMulFor != NULL &&
913                       port->hasNativeMulFor (ic, leftType, rightType))
914                     {
915                       /* Leave as native */
916                     }
917                   else
918                     {
919                       convilong (ic, ebbs[i]);
920                     }
921                 }
922             }
923
924           if (ic->op == RRC || ic->op == RLC || ic->op == LEFT_OP || ic->op == RIGHT_OP)
925             {
926               sym_link *type = operandType (IC_LEFT (ic));
927
928               if (IS_INTEGRAL (type) && getSize (type) > port->support.shift && port->support.shift >= 0)
929                 {
930                   convilong (ic, ebbs[i]);
931                 }
932             }
933         }
934     }
935 }
936
937 /*-----------------------------------------------------------------*/
938 /* isLocalWithoutDef - return 1 if sym might be used without a     */
939 /*                     defining iCode                              */
940 /*-----------------------------------------------------------------*/
941 static int
942 isLocalWithoutDef (symbol * sym)
943 {
944   if (!IS_AUTO (sym))
945     return 0;
946
947   if (IS_VOLATILE (sym->type))
948     return 0;
949
950   if (sym->_isparm)
951     return 0;
952
953   if (IS_AGGREGATE (sym->type))
954     return 0;
955
956   if (sym->addrtaken)
957     return 0;
958
959   return !sym->defs;
960 }
961
962 /*-----------------------------------------------------------------*/
963 /* replaceRegEqv - replace all local variables with their reqv     */
964 /*-----------------------------------------------------------------*/
965 static void
966 replaceRegEqv (ebbIndex * ebbi)
967 {
968   eBBlock ** ebbs = ebbi->bbOrder;
969   int count = ebbi->count;
970   int i;
971
972   /* Update the symbols' def bitvector so we know if there is   */
973   /* a defining iCode or not. Only replace a local variable     */
974   /* with its register equivalent if there is a defining iCode; */
975   /* otherwise, the port's register allocater may choke.        */
976   cseAllBlocks (ebbi, TRUE);
977
978   for (i = 0; i < count; i++)
979     {
980
981       iCode *ic;
982
983       for (ic = ebbs[i]->sch; ic; ic = ic->next)
984         {
985
986           if (SKIP_IC2 (ic))
987             continue;
988
989           if (ic->op == IFX)
990             {
991               if (IC_COND (ic) &&
992                   IS_TRUE_SYMOP (IC_COND (ic)) &&
993                   isLocalWithoutDef (OP_SYMBOL (IC_COND (ic))))
994                 {
995                   werrorfl (ic->filename, ic->lineno,
996                           W_LOCAL_NOINIT,
997                           OP_SYMBOL (IC_COND (ic))->name);
998                   OP_REQV (IC_COND (ic)) = NULL;
999                   OP_SYMBOL (IC_COND (ic))->allocreq = 1;
1000                 }
1001
1002               if (IS_TRUE_SYMOP (IC_COND (ic)) &&
1003                   OP_REQV (IC_COND (ic)))
1004                 IC_COND (ic) = opFromOpWithDU (OP_REQV (IC_COND (ic)),
1005                                              OP_SYMBOL (IC_COND (ic))->defs,
1006                                             OP_SYMBOL (IC_COND (ic))->uses);
1007
1008               continue;
1009             }
1010
1011
1012           if (ic->op == JUMPTABLE)
1013             {
1014               if (IC_JTCOND (ic) &&
1015                   IS_TRUE_SYMOP (IC_JTCOND (ic)) &&
1016                   isLocalWithoutDef (OP_SYMBOL (IC_JTCOND (ic))))
1017                 {
1018                   werrorfl (ic->filename, ic->lineno,
1019                           W_LOCAL_NOINIT,
1020                           OP_SYMBOL (IC_JTCOND (ic))->name);
1021                   OP_REQV (IC_JTCOND (ic)) = NULL;
1022                   OP_SYMBOL (IC_JTCOND (ic))->allocreq = 1;
1023                 }
1024
1025               if (IS_TRUE_SYMOP (IC_JTCOND (ic)) &&
1026                   OP_REQV (IC_JTCOND (ic)))
1027                 IC_JTCOND (ic) = opFromOpWithDU (OP_REQV (IC_JTCOND (ic)),
1028                                            OP_SYMBOL (IC_JTCOND (ic))->defs,
1029                                           OP_SYMBOL (IC_JTCOND (ic))->uses);
1030               continue;
1031             }
1032
1033           if (ic->op == RECEIVE)
1034             {
1035               if (OP_SYMBOL (IC_RESULT (ic))->addrtaken)
1036                 OP_SYMBOL (IC_RESULT (ic))->isspilt = 1;
1037             }
1038
1039           /* general case */
1040           if (IC_RESULT (ic) &&
1041               IS_TRUE_SYMOP (IC_RESULT (ic)) &&
1042               OP_REQV (IC_RESULT (ic)))
1043             {
1044               if (POINTER_SET (ic))
1045                 {
1046                   IC_RESULT (ic) = opFromOpWithDU (OP_REQV (IC_RESULT (ic)),
1047                                            OP_SYMBOL (IC_RESULT (ic))->defs,
1048                                           OP_SYMBOL (IC_RESULT (ic))->uses);
1049                   IC_RESULT (ic)->isaddr = 1;
1050                 }
1051               else
1052                 IC_RESULT (ic) = opFromOpWithDU (OP_REQV (IC_RESULT (ic)),
1053                                            OP_SYMBOL (IC_RESULT (ic))->defs,
1054                                           OP_SYMBOL (IC_RESULT (ic))->uses);
1055             }
1056
1057           if (IC_RIGHT (ic) &&
1058               IS_TRUE_SYMOP (IC_RIGHT (ic)) &&
1059               isLocalWithoutDef (OP_SYMBOL (IC_RIGHT (ic))))
1060             {
1061               werrorfl (ic->filename, ic->lineno,
1062                         W_LOCAL_NOINIT,
1063                         OP_SYMBOL (IC_RIGHT (ic))->name);
1064               OP_REQV (IC_RIGHT (ic)) = NULL;
1065               OP_SYMBOL (IC_RIGHT (ic))->allocreq = 1;
1066             }
1067
1068           if (IC_RIGHT (ic) &&
1069               IS_TRUE_SYMOP (IC_RIGHT (ic)) &&
1070               OP_REQV (IC_RIGHT (ic)))
1071             {
1072               IC_RIGHT (ic) = opFromOpWithDU (OP_REQV (IC_RIGHT (ic)),
1073                                             OP_SYMBOL (IC_RIGHT (ic))->defs,
1074                                            OP_SYMBOL (IC_RIGHT (ic))->uses);
1075               IC_RIGHT (ic)->isaddr = 0;
1076             }
1077
1078           if (IC_LEFT (ic) &&
1079               IS_TRUE_SYMOP (IC_LEFT (ic)) &&
1080               isLocalWithoutDef (OP_SYMBOL (IC_LEFT (ic))))
1081             {
1082               werrorfl (ic->filename, ic->lineno,
1083                         W_LOCAL_NOINIT,
1084                         OP_SYMBOL (IC_LEFT (ic))->name);
1085               OP_REQV (IC_LEFT (ic)) = NULL;
1086               OP_SYMBOL (IC_LEFT (ic))->allocreq = 1;
1087             }
1088
1089           if (IC_LEFT (ic) &&
1090               IS_TRUE_SYMOP (IC_LEFT (ic)) &&
1091               OP_REQV (IC_LEFT (ic)))
1092             {
1093               IC_LEFT (ic) = opFromOpWithDU (OP_REQV (IC_LEFT (ic)),
1094                                              OP_SYMBOL (IC_LEFT (ic))->defs,
1095                                              OP_SYMBOL (IC_LEFT (ic))->uses);
1096               IC_LEFT (ic)->isaddr = 0;
1097             }
1098         }
1099     }
1100 }
1101
1102 /*-----------------------------------------------------------------*/
1103 /* findReqv - search for a register equivalent                     */
1104 /*-----------------------------------------------------------------*/
1105 operand *
1106 findReqv (symbol * prereqv, eBBlock ** ebbs, int count)
1107 {
1108   int i;
1109   iCode * ic;
1110
1111   /* for all blocks do */
1112   for (i=0; i<count; i++)
1113     {
1114       /* for all instructions in the block do */
1115       for (ic = ebbs[i]->sch; ic; ic = ic->next)
1116         {
1117           if (ic->op == IFX)
1118             {
1119               if (IS_ITEMP (IC_COND (ic))
1120                   && OP_SYMBOL (IC_COND (ic))->prereqv == prereqv)
1121                 return IC_COND (ic);
1122             }
1123           else if (ic->op == JUMPTABLE)
1124             {
1125               if (IS_ITEMP (IC_JTCOND (ic))
1126                   && OP_SYMBOL (IC_JTCOND (ic))->prereqv == prereqv)
1127                 return IC_JTCOND (ic);
1128             }
1129           else
1130             {
1131               if (IS_ITEMP (IC_LEFT (ic))
1132                   && OP_SYMBOL (IC_LEFT (ic))->prereqv == prereqv)
1133                 return IC_LEFT (ic);
1134               if (IS_ITEMP (IC_RIGHT (ic))
1135                   && OP_SYMBOL (IC_RIGHT (ic))->prereqv == prereqv)
1136                 return IC_RIGHT (ic);
1137               if (IS_ITEMP (IC_RESULT (ic))
1138                   && OP_SYMBOL (IC_RESULT (ic))->prereqv == prereqv)
1139                 return IC_RESULT (ic);
1140             }
1141         }
1142     }
1143
1144   return NULL;
1145 }
1146
1147 /*-----------------------------------------------------------------*/
1148 /* killDeadCode - eliminates dead assignments                      */
1149 /*-----------------------------------------------------------------*/
1150 int
1151 killDeadCode (ebbIndex * ebbi)
1152 {
1153   eBBlock ** ebbs = ebbi->dfOrder;
1154   int count = ebbi->count;
1155   int change = 1;
1156   int gchange = 0;
1157   int i = 0;
1158
1159
1160   /* basic algorithm :-                                          */
1161   /* first the exclusion rules :-                                */
1162   /*  1. if result is a global or volatile then skip             */
1163   /*  2. if assignment and result is a temp & isaddr  then skip  */
1164   /*     since this means array & pointer access, will be taken  */
1165   /*     care of by alias analysis.                              */
1166   /*  3. if the result is used in the remainder of the block skip */
1167   /*  4. if this definition does not reach the end of the block  */
1168   /*     i.e. the result is not present in the outExprs then KILL */
1169   /*  5. if it reaches the end of block & is used by some success */
1170   /*     or then skip                                            */
1171   /*     else            KILL                                    */
1172   /* this whole process is carried on iteratively till no change */
1173   while (1)
1174     {
1175
1176       change = 0;
1177       /* for all blocks do */
1178       for (i = 0; i < count; i++)
1179         {
1180           iCode *ic;
1181
1182           /* for all instructions in the block do */
1183           for (ic = ebbs[i]->sch; ic; ic = ic->next)
1184             {
1185               int kill, j;
1186               kill = 0;
1187
1188               if (SKIP_IC (ic) ||
1189                   ic->op == IFX ||
1190                   ic->op == RETURN ||
1191                   ic->op == DUMMY_READ_VOLATILE ||
1192                   ic->op == CRITICAL ||
1193                   ic->op == ENDCRITICAL)
1194                 continue;
1195
1196               /* Since both IFX & JUMPTABLE (in SKIP_IC) have been tested for */
1197               /* it is now safe to assume IC_LEFT, IC_RIGHT, & IC_RESULT are  */
1198               /* valid. */
1199
1200               /* if the result is volatile then continue */
1201               if (IC_RESULT (ic) && isOperandVolatile (IC_RESULT (ic), FALSE))
1202                 continue;
1203
1204               /* if the result is a temp & isaddr then skip */
1205               if (IC_RESULT (ic) && POINTER_SET (ic))
1206                 continue;
1207
1208               if (POINTER_GET (ic) && IS_VOLATILE (operandType (IC_LEFT (ic))->next)
1209                   && !SPIL_LOC (IC_RESULT (ic)))
1210                 continue;
1211
1212               /* if the result is used in the remainder of the */
1213               /* block then skip */
1214               if (usedInRemaining (IC_RESULT (ic), ic->next))
1215                 continue;
1216
1217               /* does this definition reach the end of the block
1218                  or the usage is zero then we can kill */
1219               if (!bitVectBitValue (ebbs[i]->outDefs, ic->key))
1220                 kill = 1;       /* if not we can kill it */
1221               else
1222                 {
1223                   /* if this is a global variable or function parameter */
1224                   /* we cannot kill anyway             */
1225                   if (isOperandGlobal (IC_RESULT (ic)) ||
1226                       (OP_SYMBOL (IC_RESULT (ic))->_isparm &&
1227                        !OP_SYMBOL (IC_RESULT (ic))->ismyparm))
1228                     continue;
1229
1230                   /* if we are sure there are no usages */
1231                   if (bitVectIsZero (OP_USES (IC_RESULT (ic))))
1232                     {
1233                       kill = 1;
1234                       goto kill;
1235                     }
1236
1237                   /* reset visited flag */
1238                   for (j = 0; j < count; ebbs[j++]->visited = 0);
1239
1240                   /* find out if this definition is alive */
1241                   if (applyToSet (ebbs[i]->succList,
1242                                   isDefAlive,
1243                                   ic))
1244                     continue;
1245
1246                   kill = 1;
1247                 }
1248
1249             kill:
1250               /* kill this one if required */
1251               if (kill)
1252                 {
1253                   bool volLeft = IS_SYMOP (IC_LEFT (ic))
1254                                  && isOperandVolatile (IC_LEFT (ic), FALSE);
1255                   bool volRight = IS_SYMOP (IC_RIGHT (ic))
1256                                   && isOperandVolatile (IC_RIGHT (ic), FALSE);
1257
1258                   /* a dead address-of operation should die, even if volatile */
1259                   if (ic->op == ADDRESS_OF)
1260                     volLeft = FALSE;
1261
1262                   if (ic->next && ic->seqPoint == ic->next->seqPoint
1263                       && (ic->next->op == '+' || ic->next->op == '-'))
1264                     {
1265                       if (isOperandEqual (IC_LEFT(ic), IC_LEFT(ic->next))
1266                           || isOperandEqual (IC_LEFT(ic), IC_RIGHT(ic->next)))
1267                         volLeft = FALSE;
1268                       if (isOperandEqual (IC_RIGHT(ic), IC_LEFT(ic->next))
1269                           || isOperandEqual (IC_RIGHT(ic), IC_RIGHT(ic->next)))
1270                         volRight = FALSE;
1271                     }
1272
1273                   if (POINTER_GET (ic) && IS_VOLATILE (operandType (IC_LEFT (ic))->next))
1274                     {
1275                       if (SPIL_LOC (IC_RESULT (ic)))
1276                         {
1277                           IC_RESULT (ic) = newiTempFromOp (IC_RESULT (ic));
1278                           SPIL_LOC (IC_RESULT (ic)) = NULL;
1279                         }
1280                       continue;
1281                     }
1282
1283                   change = 1;
1284                   gchange++;
1285
1286                   /* now delete from defUseSet */
1287                   deleteItemIf (&ebbs[i]->outExprs, ifDiCodeIsX, ic);
1288                   bitVectUnSetBit (ebbs[i]->outDefs, ic->key);
1289
1290                   /* and defset of the block */
1291                   bitVectUnSetBit (ebbs[i]->defSet, ic->key);
1292
1293                   /* If this is the last of a register equivalent, */
1294                   /* look for a successor register equivalent. */
1295                   bitVectUnSetBit (OP_DEFS (IC_RESULT (ic)), ic->key);
1296                   if (IS_ITEMP (IC_RESULT (ic))
1297                       && OP_SYMBOL (IC_RESULT (ic))->isreqv
1298                       && bitVectIsZero (OP_DEFS (IC_RESULT (ic))))
1299                     {
1300                       symbol * resultsym = OP_SYMBOL (IC_RESULT (ic));
1301                       symbol * prereqv = resultsym->prereqv;
1302
1303                       if (prereqv && prereqv->reqv && (OP_SYMBOL (prereqv->reqv) == resultsym))
1304                         {
1305                           operand * newreqv;
1306
1307                           IC_RESULT (ic) = NULL;
1308                           newreqv = findReqv (prereqv, ebbs, count);
1309                           if (newreqv)
1310                             {
1311                               prereqv->reqv = newreqv;
1312                             }
1313                         }
1314                     }
1315
1316                   /* delete the result */
1317                   IC_RESULT (ic) = NULL;
1318
1319                   if (volLeft || volRight)
1320                     {
1321                       /* something is volatile, so keep the iCode */
1322                       /* and change the operator instead */
1323                       ic->op = DUMMY_READ_VOLATILE;
1324
1325                       /* keep only the volatile operands */
1326                       if (!volLeft)
1327                         IC_LEFT (ic) = NULL;
1328                       if (!volRight)
1329                         IC_RIGHT (ic) = NULL;
1330                     }
1331                   else
1332                     {
1333                       /* nothing is volatile, eliminate the iCode */
1334                       remiCodeFromeBBlock (ebbs[i], ic);
1335
1336                       /* for the left & right remove the usage */
1337                       if (IS_SYMOP (IC_LEFT (ic)))
1338                         bitVectUnSetBit (OP_USES (IC_LEFT (ic)), ic->key);
1339
1340                       if (IS_SYMOP (IC_RIGHT (ic)))
1341                         bitVectUnSetBit (OP_USES (IC_RIGHT (ic)), ic->key);
1342                     }
1343                 }
1344
1345             }                   /* end of all instructions */
1346
1347           if (!ebbs[i]->sch && !ebbs[i]->noPath)
1348             disconBBlock (ebbs[i], ebbi);
1349
1350         }                       /* end of for all blocks */
1351
1352       if (!change)
1353         break;
1354     }                           /* end of while(1) */
1355
1356   return gchange;
1357 }
1358
1359 /*-----------------------------------------------------------------*/
1360 /* printCyclomatic - prints the cyclomatic information             */
1361 /*-----------------------------------------------------------------*/
1362 static void
1363 printCyclomatic (eBBlock ** ebbs, int count)
1364 {
1365   int nEdges = elementsInSet (graphEdges);
1366   int i, nNodes = 0;
1367
1368   for (i = 0; i < count; i++)
1369     nNodes += (!ebbs[i]->noPath);
1370
1371   /* print the information */
1372   werror (I_CYCLOMATIC, currFunc->name, nEdges, nNodes, nEdges - nNodes + 2);
1373 }
1374
1375 /*-----------------------------------------------------------------*/
1376 /* discardDeadParamReceives - remove any RECEIVE opcodes which     */
1377 /* refer to dead variables.                                        */
1378 /*-----------------------------------------------------------------*/
1379 static void
1380 discardDeadParamReceives (eBBlock ** ebbs, int count)
1381 {
1382   int i;
1383   iCode *ic;
1384   iCode dummyIcode;
1385
1386   for (i = 0; i < count; i++)
1387     {
1388       for (ic = ebbs[i]->sch; ic; ic = ic->next)
1389         {
1390           if (ic->op == RECEIVE)
1391             {
1392               if (IC_RESULT (ic) && OP_SYMBOL (IC_RESULT (ic))
1393                   && !OP_SYMBOL (IC_RESULT (ic))->used)
1394                 {
1395 #if 0
1396                   fprintf (stderr, "discarding dead receive for %s\n",
1397                            OP_SYMBOL (IC_RESULT (ic))->name);
1398 #endif
1399                   dummyIcode.next = ic->next;
1400                   remiCodeFromeBBlock (ebbs[i], ic);
1401                   ic = &dummyIcode;
1402                 }
1403             }
1404         }
1405     }
1406 }
1407
1408 /*-----------------------------------------------------------------*/
1409 /* optimizeCastCast - remove unneeded intermediate casts.          */
1410 /* Integer promotion may cast (un)signed char to int and then      */
1411 /* recast the int to (un)signed long. If the signedness of the     */
1412 /* char and long are the same, the cast can be safely performed in */
1413 /* a single step.                                                  */
1414 /*-----------------------------------------------------------------*/
1415 static void
1416 optimizeCastCast (eBBlock ** ebbs, int count)
1417 {
1418   int i;
1419   iCode *ic;
1420   iCode *uic;
1421   sym_link * type1;
1422   sym_link * type2;
1423   sym_link * type3;
1424   symbol * sym;
1425
1426   for (i = 0; i < count; i++)
1427     {
1428       for (ic = ebbs[i]->sch; ic; ic = ic->next)
1429         {
1430
1431           if (ic->op == CAST && IC_RESULT (ic) && IS_ITEMP (IC_RESULT (ic)))
1432             {
1433               type1 = operandType (IC_RIGHT (ic));
1434               type2 = operandType (IC_RESULT (ic));
1435
1436               /* Look only for a cast from an integer type to an */
1437               /* integer type that has no loss of bits */
1438               if (!IS_INTEGRAL (type1) || !IS_INTEGRAL (type2))
1439                 continue;
1440               if (getSize (type2) < getSize (type1))
1441                 continue;
1442
1443               /* There must be only one use of this first result */
1444               if (bitVectnBitsOn (OP_USES (IC_RESULT (ic))) != 1)
1445                 continue;
1446
1447               /* This use must be a second cast */
1448               uic = hTabItemWithKey (iCodehTab,
1449                         bitVectFirstBit (OP_USES (IC_RESULT (ic))));
1450               if (!uic || uic->op != CAST)
1451                 continue;
1452
1453               /* It must be a cast to another integer type that */
1454               /* has no loss of bits */
1455               type3 = operandType (IC_RESULT (uic));
1456               if (!IS_INTEGRAL (type3))
1457                  continue;
1458               if (getSize (type3) < getSize (type2))
1459                  continue;
1460
1461               /* The signedness between the first and last types */
1462               /* must match */
1463               if (SPEC_USIGN (type3) != SPEC_USIGN (type1))
1464                  continue;
1465
1466               /* Change the first cast to a simple assignment and */
1467               /* let the second cast do all the work */
1468               ic->op = '=';
1469               IC_LEFT (ic) = NULL;
1470               sym = OP_SYMBOL (IC_RESULT (ic));
1471               sym->type = copyLinkChain (type1);
1472               sym->etype = getSpec (sym->type);
1473             }
1474         }
1475     }
1476 }
1477
1478 /*-----------------------------------------------------------------*/
1479 /* eBBlockFromiCode - creates extended basic blocks from iCode     */
1480 /*                    will return an array of eBBlock pointers     */
1481 /*-----------------------------------------------------------------*/
1482 eBBlock **
1483 eBBlockFromiCode (iCode * ic)
1484 {
1485   ebbIndex *ebbi = NULL;
1486   int change = 1;
1487   int lchange = 0;
1488   int kchange = 0;
1489   hTab *loops;
1490
1491   /* if nothing passed then return nothing */
1492   if (!ic)
1493     return NULL;
1494
1495   eBBNum = 0;
1496
1497   /* optimize the chain for labels & gotos
1498      this will eliminate redundant labels and
1499      will change jump to jumps by jumps */
1500   ic = iCodeLabelOptimize (ic);
1501
1502   /* break it down into basic blocks */
1503   ebbi = iCodeBreakDown (ic);
1504
1505   /* hash the iCode keys so that we can quickly index */
1506   /* them in the rest of the optimization steps */
1507   setToNull ((void *) &iCodehTab);
1508   iCodehTab = newHashTable (iCodeKey);
1509   hashiCodeKeys (ebbi->bbOrder, ebbi->count);
1510
1511   /* compute the control flow */
1512   computeControlFlow (ebbi);
1513
1514   /* dumpraw if asked for */
1515   if (options.dump_raw)
1516     dumpEbbsToFileExt (DUMP_RAW0, ebbi);
1517
1518   /* replace the local variables with their
1519      register equivalents : the liveRange computation
1520      along with the register allocation will determine
1521      if it finally stays in the registers */
1522   replaceRegEqv (ebbi);
1523
1524   /* create loop regions */
1525   loops = createLoopRegions (ebbi);
1526
1527   /* dumpraw if asked for */
1528   if (options.dump_raw)
1529     dumpEbbsToFileExt (DUMP_RAW1, ebbi);
1530
1531   optimizeCastCast (ebbi->bbOrder, ebbi->count);
1532
1533   /* do common subexpression elimination for each block */
1534   change = cseAllBlocks (ebbi, FALSE);
1535
1536   /* dumpraw if asked for */
1537   if (options.dump_raw)
1538     dumpEbbsToFileExt (DUMP_CSE, ebbi);
1539
1540   /* compute the data flow */
1541   computeDataFlow (ebbi);
1542
1543   /* dumpraw if asked for */
1544   if (options.dump_raw)
1545     dumpEbbsToFileExt (DUMP_DFLOW, ebbi);
1546
1547   /* global common subexpression elimination  */
1548   if (optimize.global_cse)
1549     {
1550       change += cseAllBlocks (ebbi, FALSE);
1551       if (options.dump_gcse)
1552         dumpEbbsToFileExt (DUMP_GCSE, ebbi);
1553     }
1554   else
1555     {
1556       // compute the dataflow only
1557       assert(cseAllBlocks (ebbi, TRUE)==0);
1558     }
1559   /* kill dead code */
1560   kchange = killDeadCode (ebbi);
1561
1562   if (options.dump_kill)
1563     dumpEbbsToFileExt (DUMP_DEADCODE, ebbi);
1564
1565   /* do loop optimizations */
1566   change += (lchange = loopOptimizations (loops, ebbi));
1567   if (options.dump_loop)
1568     dumpEbbsToFileExt (DUMP_LOOP, ebbi);
1569
1570   /* recompute the data flow and apply global cse again
1571      if loops optimizations or dead code caused a change:
1572      loops will brings out of the loop which then may be
1573      available for use in the later blocks: dead code
1574      elimination could potentially disconnect some blocks
1575      conditional flow may be efected so we need to apply
1576      subexpression once more */
1577   if (lchange || kchange)
1578     {
1579       computeDataFlow (ebbi);
1580       change += cseAllBlocks (ebbi, FALSE);
1581       if (options.dump_loop)
1582         dumpEbbsToFileExt (DUMP_LOOPG, ebbi);
1583
1584       /* if loop optimizations caused a change then do
1585          dead code elimination once more : this will
1586          get rid of the extra assignments to the induction
1587          variables created during loop optimizations */
1588       killDeadCode (ebbi);
1589
1590       if (options.dump_loop)
1591         dumpEbbsToFileExt (DUMP_LOOPD, ebbi);
1592
1593     }
1594
1595   /* sort it back by block number */
1596   //qsort (ebbs, saveCount, sizeof (eBBlock *), bbNumCompare);
1597
1598   if (!options.lessPedantic) {
1599     // this is a good place to check missing return values
1600     if (currFunc) {
1601       // the user is on his own with naked functions...
1602       if (!IS_VOID(currFunc->etype)
1603        && !FUNC_ISNAKED(currFunc->type)) {
1604         eBBlock *bp;
1605         // make sure all predecessors of the last block end in a return
1606         for (bp=setFirstItem(ebbi->bbOrder[ebbi->count-1]->predList);
1607              bp;
1608              bp=setNextItem(ebbi->bbOrder[ebbi->count-1]->predList)) {
1609           if (bp->ech->op != RETURN) {
1610             werrorfl (bp->ech->filename, bp->ech->lineno,
1611                       W_VOID_FUNC, currFunc->name);
1612           }
1613         }
1614       }
1615     }
1616   }
1617
1618   /* if cyclomatic info requested then print it */
1619   if (options.cyclomatic)
1620     printCyclomatic (ebbi->bbOrder, ebbi->count);
1621
1622   /* convert operations with support routines
1623      written in C to function calls : I am doing
1624      this at this point since I want all the
1625      operations to be as they are for optimizations */
1626   convertToFcall (ebbi->bbOrder, ebbi->count);
1627
1628   /* compute the live ranges */
1629   computeLiveRanges (ebbi->bbOrder, ebbi->count, TRUE);
1630
1631   if (options.dump_range)
1632     dumpEbbsToFileExt (DUMP_RANGE, ebbi);
1633
1634   /* Now that we have the live ranges, discard parameter
1635    * receives for unused parameters.
1636    */
1637   discardDeadParamReceives (ebbi->bbOrder, ebbi->count);
1638
1639   /* allocate registers & generate code */
1640   port->assignRegisters (ebbi);
1641
1642   /* throw away blocks */
1643   setToNull ((void *) &graphEdges);
1644
1645   return NULL;
1646 }
1647
1648
1649 /* (add-hook 'c-mode-hook (lambda () (setq c-basic-offset 4))) */