* src/pic/gen.h: reverted the Q&D solution for the bug, found by Jim Paris,
[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, sym_link * type, int op)
658 {
659   symbol *func = NULL;
660   iCode *ip = ic->next;
661   iCode *newic;
662   char *filename = ic->filename;
663   int lineno = ic->lineno;
664   int bwd;
665   int su;
666   int bytesPushed=0;
667
668   remiCodeFromeBBlock (ebp, ic);
669
670   /* depending on the type */
671   for (bwd = 0; bwd < 3; bwd++)
672     {
673       for (su = 0; su < 2; su++)
674         {
675           if (compareType (type, __multypes[bwd][su]) == 1)
676             {
677               if (op == '*')
678                 func = __muldiv[0][bwd][su];
679               else if (op == '/')
680                 func = __muldiv[1][bwd][su];
681               else if (op == '%')
682                 func = __muldiv[2][bwd][su];
683               else if (op == RRC)
684                 func = __rlrr[1][bwd][su];
685               else if (op == RLC)
686                 func = __rlrr[0][bwd][su];
687               else if (op == RIGHT_OP)
688                 func = __rlrr[1][bwd][su];
689               else if (op == LEFT_OP)
690                 func = __rlrr[0][bwd][su];
691               else
692                 assert (0);
693               goto found;
694             }
695         }
696     }
697   assert (0);
698 found:
699   /* if int & long support routines NOT compiled as reentrant */
700   if (!options.intlong_rent)
701     {
702       /* first one */
703         if (IS_REGPARM (FUNC_ARGS(func->type)->etype)) {
704             newic = newiCode (SEND, IC_LEFT (ic), NULL);
705             newic->argreg = SPEC_ARGREG(FUNC_ARGS(func->type)->etype);
706         }
707       else
708         {
709           newic = newiCode ('=', NULL, IC_LEFT (ic));
710           IC_RESULT (newic) = operandFromValue (FUNC_ARGS(func->type));
711         }
712       addiCodeToeBBlock (ebp, newic, ip);
713       newic->filename = filename;
714       newic->lineno = lineno;
715
716       /* second one */
717       if (IS_REGPARM (FUNC_ARGS(func->type)->next->etype)) {
718           newic = newiCode (SEND, IC_RIGHT (ic), NULL);
719           newic->argreg = SPEC_ARGREG(FUNC_ARGS(func->type)->next->etype);
720       }
721       else
722         {
723           newic = newiCode ('=', NULL, IC_RIGHT (ic));
724           IC_RESULT (newic) = operandFromValue (FUNC_ARGS(func->type)->next);
725         }
726       addiCodeToeBBlock (ebp, newic, ip);
727       newic->filename = filename;
728       newic->lineno = lineno;
729
730     }
731   else
732     {
733       /* compiled as reentrant then push */
734       /* push right */
735       if (IS_REGPARM (FUNC_ARGS(func->type)->next->etype))
736         {
737           newic = newiCode (SEND, IC_RIGHT (ic), NULL);
738           newic->argreg = SPEC_ARGREG(FUNC_ARGS(func->type)->next->etype);
739         }
740       else
741         {
742           newic = newiCode (IPUSH, IC_RIGHT (ic), NULL);
743           newic->parmPush = 1;
744
745           bytesPushed += getSize(operandType(IC_RIGHT(ic)));
746         }
747       addiCodeToeBBlock (ebp, newic, ip);
748       newic->filename = filename;
749       newic->lineno = lineno;
750
751       /* insert push left */
752       if (IS_REGPARM (FUNC_ARGS(func->type)->etype))
753         {
754           newic = newiCode (SEND, IC_LEFT (ic), NULL);
755           newic->argreg = SPEC_ARGREG(FUNC_ARGS(func->type)->etype);
756         }
757       else
758         {
759           newic = newiCode (IPUSH, IC_LEFT (ic), NULL);
760           newic->parmPush = 1;
761
762           bytesPushed += getSize(operandType(IC_LEFT(ic)));
763         }
764       addiCodeToeBBlock (ebp, newic, ip);
765       newic->filename = filename;
766       newic->lineno = lineno;
767
768     }
769
770   /* for the result */
771   newic = newiCode (CALL, operandFromSymbol (func), NULL);
772   IC_RESULT (newic) = IC_RESULT (ic);
773   newic->filename = filename;
774   newic->lineno = lineno;
775   newic->parmBytes+=bytesPushed; // to clear the stack after the call
776   ebp->hasFcall = 1;
777   if (currFunc)
778     FUNC_HASFCALL (currFunc->type) = 1;
779
780   if(TARGET_IS_PIC || TARGET_IS_PIC16) {
781         /* normally these functions aren't marked external, so we can use their
782          * _extern field to marked as already added to symbol table */
783
784         if(!SPEC_EXTR(func->etype)) {
785             memmap *seg = SPEC_OCLS(OP_SYMBOL(IC_LEFT(newic))->etype);
786
787                 SPEC_EXTR(func->etype) = 1;
788                 seg = SPEC_OCLS( func->etype );
789                 addSet(&seg->syms, func);
790         }
791   }
792
793   addiCodeToeBBlock (ebp, newic, ip);
794 }
795
796 /*-----------------------------------------------------------------*/
797 /* convertToFcall - converts some operations to fcalls             */
798 /*-----------------------------------------------------------------*/
799 static void
800 convertToFcall (eBBlock ** ebbs, int count)
801 {
802   int i;
803
804   /* for all blocks do */
805   for (i = 0; i < count; i++)
806     {
807       iCode *ic;
808
809       /* for all instructions in the block do */
810       for (ic = ebbs[i]->sch; ic; ic = ic->next)
811         {
812
813           /* floating point operations are
814              converted to function calls */
815           if ((IS_CONDITIONAL (ic) ||
816                IS_ARITHMETIC_OP (ic)) &&
817               (IS_FLOAT (operandType (IC_RIGHT (ic))) ||
818                IS_FIXED( operandType (IC_RIGHT (ic)))))
819             {
820               cnvToFcall (ic, ebbs[i]);
821             }
822
823           /* casting is a little different */
824           if (ic->op == CAST)
825             {
826               if (IS_FLOAT (operandType (IC_RIGHT (ic))))
827                 cnvFromFloatCast (ic, ebbs[i]);
828               else if (IS_FLOAT (operandType (IC_LEFT (ic))))
829                 cnvToFloatCast (ic, ebbs[i]);
830               if (IS_FIXED16X16 (operandType (IC_RIGHT (ic))))
831                 cnvFromFixed16x16Cast (ic, ebbs[i]);
832               else if (IS_FIXED16X16 (operandType (IC_LEFT (ic))))
833                 cnvToFixed16x16Cast (ic, ebbs[i]);
834             }
835
836           // Easy special case which avoids function call: modulo by a literal power
837           // of two can be replaced by a bitwise AND.
838           if (ic->op == '%' && isOperandLiteral(IC_RIGHT(ic)) &&
839               IS_UNSIGNED(operandType(IC_LEFT(ic))))
840             {
841               unsigned litVal = abs((unsigned) double2ul (operandLitValue(IC_RIGHT(ic))));
842
843               /* modulo by 1: no remainder */
844               if (litVal == 1)
845                 {
846                   ic->op = '=';
847                   IC_RIGHT (ic) = operandFromLit(0);
848                   IC_LEFT (ic) = NULL;
849                   continue;
850                 }
851               // See if literal value is a power of 2.
852               while (litVal && !(litVal & 1))
853                 {
854                   litVal >>= 1;
855                 }
856               if (litVal)
857                 {
858                   // discard lowest set bit.
859                   litVal >>= 1;
860                 }
861
862               if (!litVal)
863                 {
864                   ic->op = BITWISEAND;
865                   IC_RIGHT(ic) = operandFromLit(operandLitValue(IC_RIGHT(ic)) - 1);
866                   continue;
867                 }
868             }
869
870           /* if long / int mult or divide or mod */
871           if (ic->op == '*' || ic->op == '/' || ic->op == '%')
872             {
873               sym_link *leftType = operandType (IC_LEFT (ic));
874
875               if (IS_INTEGRAL (leftType) && getSize (leftType) > port->support.muldiv)
876                 {
877                   sym_link *rightType = operandType (IC_RIGHT (ic));
878
879                   if (port->hasNativeMulFor != NULL &&
880                       port->hasNativeMulFor (ic, leftType, rightType))
881                     {
882                       /* Leave as native */
883                     }
884                   else
885                     {
886                       convilong (ic, ebbs[i], leftType, ic->op);
887                     }
888                 }
889             }
890
891           if (ic->op == RRC || ic->op == RLC || ic->op == LEFT_OP || ic->op == RIGHT_OP)
892             {
893               sym_link *type = operandType (IC_LEFT (ic));
894
895               if (IS_INTEGRAL (type) && getSize (type) > port->support.shift && port->support.shift >= 0)
896                 {
897                   convilong (ic, ebbs[i], type, ic->op);
898                 }
899             }
900         }
901     }
902 }
903
904 /*-----------------------------------------------------------------*/
905 /* isLocalWithoutDef - return 1 if sym might be used without a     */
906 /*                     defining iCode                              */
907 /*-----------------------------------------------------------------*/
908 static int
909 isLocalWithoutDef (symbol * sym)
910 {
911   if (!IS_AUTO (sym))
912     return 0;
913
914   if (IS_VOLATILE (sym->type))
915     return 0;
916
917   if (sym->_isparm)
918     return 0;
919
920   if (IS_AGGREGATE (sym->type))
921     return 0;
922
923   if (sym->addrtaken)
924     return 0;
925
926   return !sym->defs;
927 }
928
929 /*-----------------------------------------------------------------*/
930 /* replaceRegEqv - replace all local variables with their reqv     */
931 /*-----------------------------------------------------------------*/
932 static void
933 replaceRegEqv (ebbIndex * ebbi)
934 {
935   eBBlock ** ebbs = ebbi->bbOrder;
936   int count = ebbi->count;
937   int i;
938
939   /* Update the symbols' def bitvector so we know if there is   */
940   /* a defining iCode or not. Only replace a local variable     */
941   /* with its register equivalent if there is a defining iCode; */
942   /* otherwise, the port's register allocater may choke.        */
943   cseAllBlocks (ebbi, TRUE);
944
945   for (i = 0; i < count; i++)
946     {
947
948       iCode *ic;
949
950       for (ic = ebbs[i]->sch; ic; ic = ic->next)
951         {
952
953           if (SKIP_IC2 (ic))
954             continue;
955
956           if (ic->op == IFX)
957             {
958               if (IC_COND (ic) &&
959                   IS_TRUE_SYMOP (IC_COND (ic)) &&
960                   isLocalWithoutDef (OP_SYMBOL (IC_COND (ic))))
961                 {
962                   werrorfl (ic->filename, ic->lineno,
963                           W_LOCAL_NOINIT,
964                           OP_SYMBOL (IC_COND (ic))->name);
965                   OP_REQV (IC_COND (ic)) = NULL;
966                   OP_SYMBOL (IC_COND (ic))->allocreq = 1;
967                 }
968
969               if (IS_TRUE_SYMOP (IC_COND (ic)) &&
970                   OP_REQV (IC_COND (ic)))
971                 IC_COND (ic) = opFromOpWithDU (OP_REQV (IC_COND (ic)),
972                                              OP_SYMBOL (IC_COND (ic))->defs,
973                                             OP_SYMBOL (IC_COND (ic))->uses);
974
975               continue;
976             }
977
978
979           if (ic->op == JUMPTABLE)
980             {
981               if (IC_JTCOND (ic) &&
982                   IS_TRUE_SYMOP (IC_JTCOND (ic)) &&
983                   isLocalWithoutDef (OP_SYMBOL (IC_JTCOND (ic))))
984                 {
985                   werrorfl (ic->filename, ic->lineno,
986                           W_LOCAL_NOINIT,
987                           OP_SYMBOL (IC_JTCOND (ic))->name);
988                   OP_REQV (IC_JTCOND (ic)) = NULL;
989                   OP_SYMBOL (IC_JTCOND (ic))->allocreq = 1;
990                 }
991
992               if (IS_TRUE_SYMOP (IC_JTCOND (ic)) &&
993                   OP_REQV (IC_JTCOND (ic)))
994                 IC_JTCOND (ic) = opFromOpWithDU (OP_REQV (IC_JTCOND (ic)),
995                                            OP_SYMBOL (IC_JTCOND (ic))->defs,
996                                           OP_SYMBOL (IC_JTCOND (ic))->uses);
997               continue;
998             }
999
1000           if (ic->op == RECEIVE)
1001             {
1002               if (OP_SYMBOL (IC_RESULT (ic))->addrtaken)
1003                 OP_SYMBOL (IC_RESULT (ic))->isspilt = 1;
1004             }
1005
1006           /* general case */
1007           if (IC_RESULT (ic) &&
1008               IS_TRUE_SYMOP (IC_RESULT (ic)) &&
1009               OP_REQV (IC_RESULT (ic)))
1010             {
1011               if (POINTER_SET (ic))
1012                 {
1013                   IC_RESULT (ic) = opFromOpWithDU (OP_REQV (IC_RESULT (ic)),
1014                                            OP_SYMBOL (IC_RESULT (ic))->defs,
1015                                           OP_SYMBOL (IC_RESULT (ic))->uses);
1016                   IC_RESULT (ic)->isaddr = 1;
1017                 }
1018               else
1019                 IC_RESULT (ic) = opFromOpWithDU (OP_REQV (IC_RESULT (ic)),
1020                                            OP_SYMBOL (IC_RESULT (ic))->defs,
1021                                           OP_SYMBOL (IC_RESULT (ic))->uses);
1022             }
1023
1024           if (IC_RIGHT (ic) &&
1025               IS_TRUE_SYMOP (IC_RIGHT (ic)) &&
1026               isLocalWithoutDef (OP_SYMBOL (IC_RIGHT (ic))))
1027             {
1028               werrorfl (ic->filename, ic->lineno,
1029                         W_LOCAL_NOINIT,
1030                         OP_SYMBOL (IC_RIGHT (ic))->name);
1031               OP_REQV (IC_RIGHT (ic)) = NULL;
1032               OP_SYMBOL (IC_RIGHT (ic))->allocreq = 1;
1033             }
1034
1035           if (IC_RIGHT (ic) &&
1036               IS_TRUE_SYMOP (IC_RIGHT (ic)) &&
1037               OP_REQV (IC_RIGHT (ic)))
1038             {
1039               IC_RIGHT (ic) = opFromOpWithDU (OP_REQV (IC_RIGHT (ic)),
1040                                             OP_SYMBOL (IC_RIGHT (ic))->defs,
1041                                            OP_SYMBOL (IC_RIGHT (ic))->uses);
1042               IC_RIGHT (ic)->isaddr = 0;
1043             }
1044
1045           if (IC_LEFT (ic) &&
1046               IS_TRUE_SYMOP (IC_LEFT (ic)) &&
1047               isLocalWithoutDef (OP_SYMBOL (IC_LEFT (ic))))
1048             {
1049               werrorfl (ic->filename, ic->lineno,
1050                         W_LOCAL_NOINIT,
1051                         OP_SYMBOL (IC_LEFT (ic))->name);
1052               OP_REQV (IC_LEFT (ic)) = NULL;
1053               OP_SYMBOL (IC_LEFT (ic))->allocreq = 1;
1054             }
1055
1056           if (IC_LEFT (ic) &&
1057               IS_TRUE_SYMOP (IC_LEFT (ic)) &&
1058               OP_REQV (IC_LEFT (ic)))
1059             {
1060               IC_LEFT (ic) = opFromOpWithDU (OP_REQV (IC_LEFT (ic)),
1061                                              OP_SYMBOL (IC_LEFT (ic))->defs,
1062                                              OP_SYMBOL (IC_LEFT (ic))->uses);
1063               IC_LEFT (ic)->isaddr = 0;
1064             }
1065         }
1066     }
1067 }
1068
1069 /*-----------------------------------------------------------------*/
1070 /* findReqv - search for a register equivalent                     */
1071 /*-----------------------------------------------------------------*/
1072 operand *
1073 findReqv (symbol * prereqv, eBBlock ** ebbs, int count)
1074 {
1075   int i;
1076   iCode * ic;
1077
1078   /* for all blocks do */
1079   for (i=0; i<count; i++)
1080     {
1081       /* for all instructions in the block do */
1082       for (ic = ebbs[i]->sch; ic; ic = ic->next)
1083         {
1084           if (ic->op == IFX)
1085             {
1086               if (IS_ITEMP (IC_COND (ic))
1087                   && OP_SYMBOL (IC_COND (ic))->prereqv == prereqv)
1088                 return IC_COND (ic);
1089             }
1090           else if (ic->op == JUMPTABLE)
1091             {
1092               if (IS_ITEMP (IC_JTCOND (ic))
1093                   && OP_SYMBOL (IC_JTCOND (ic))->prereqv == prereqv)
1094                 return IC_JTCOND (ic);
1095             }
1096           else
1097             {
1098               if (IS_ITEMP (IC_LEFT (ic))
1099                   && OP_SYMBOL (IC_LEFT (ic))->prereqv == prereqv)
1100                 return IC_LEFT (ic);
1101               if (IS_ITEMP (IC_RIGHT (ic))
1102                   && OP_SYMBOL (IC_RIGHT (ic))->prereqv == prereqv)
1103                 return IC_RIGHT (ic);
1104               if (IS_ITEMP (IC_RESULT (ic))
1105                   && OP_SYMBOL (IC_RESULT (ic))->prereqv == prereqv)
1106                 return IC_RESULT (ic);
1107             }
1108         }
1109     }
1110
1111   return NULL;
1112 }
1113
1114 /*-----------------------------------------------------------------*/
1115 /* killDeadCode - eliminates dead assignments                      */
1116 /*-----------------------------------------------------------------*/
1117 int
1118 killDeadCode (ebbIndex * ebbi)
1119 {
1120   eBBlock ** ebbs = ebbi->dfOrder;
1121   int count = ebbi->count;
1122   int change = 1;
1123   int gchange = 0;
1124   int i = 0;
1125
1126
1127   /* basic algorithm :-                                          */
1128   /* first the exclusion rules :-                                */
1129   /*  1. if result is a global or volatile then skip             */
1130   /*  2. if assignment and result is a temp & isaddr  then skip  */
1131   /*     since this means array & pointer access, will be taken  */
1132   /*     care of by alias analysis.                              */
1133   /*  3. if the result is used in the remainder of the block skip */
1134   /*  4. if this definition does not reach the end of the block  */
1135   /*     i.e. the result is not present in the outExprs then KILL */
1136   /*  5. if it reaches the end of block & is used by some success */
1137   /*     or then skip                                            */
1138   /*     else            KILL                                    */
1139   /* this whole process is carried on iteratively till no change */
1140   while (1)
1141     {
1142
1143       change = 0;
1144       /* for all blocks do */
1145       for (i = 0; i < count; i++)
1146         {
1147           iCode *ic;
1148
1149           /* for all instructions in the block do */
1150           for (ic = ebbs[i]->sch; ic; ic = ic->next)
1151             {
1152               int kill, j;
1153               kill = 0;
1154
1155               if (SKIP_IC (ic) ||
1156                   ic->op == IFX ||
1157                   ic->op == RETURN ||
1158                   ic->op == DUMMY_READ_VOLATILE ||
1159                   ic->op == CRITICAL ||
1160                   ic->op == ENDCRITICAL)
1161                 continue;
1162
1163               /* Since both IFX & JUMPTABLE (in SKIP_IC) have been tested for */
1164               /* it is now safe to assume IC_LEFT, IC_RIGHT, & IC_RESULT are  */
1165               /* valid. */
1166
1167               /* if the result is volatile then continue */
1168               if (IC_RESULT (ic) && isOperandVolatile (IC_RESULT (ic), FALSE))
1169                 continue;
1170
1171               /* if the result is a temp & isaddr then skip */
1172               if (IC_RESULT (ic) && POINTER_SET (ic))
1173                 continue;
1174
1175               if (POINTER_GET (ic) && IS_VOLATILE (operandType (IC_LEFT (ic))->next)
1176                   && !SPIL_LOC (IC_RESULT (ic)))
1177                 continue;
1178
1179               /* if the result is used in the remainder of the */
1180               /* block then skip */
1181               if (usedInRemaining (IC_RESULT (ic), ic->next))
1182                 continue;
1183
1184               /* does this definition reach the end of the block
1185                  or the usage is zero then we can kill */
1186               if (!bitVectBitValue (ebbs[i]->outDefs, ic->key))
1187                 kill = 1;       /* if not we can kill it */
1188               else
1189                 {
1190                   /* if this is a global variable or function parameter */
1191                   /* we cannot kill anyway             */
1192                   if (isOperandGlobal (IC_RESULT (ic)) ||
1193                       (OP_SYMBOL (IC_RESULT (ic))->_isparm &&
1194                        !OP_SYMBOL (IC_RESULT (ic))->ismyparm))
1195                     continue;
1196
1197                   /* if we are sure there are no usages */
1198                   if (bitVectIsZero (OP_USES (IC_RESULT (ic))))
1199                     {
1200                       kill = 1;
1201                       goto kill;
1202                     }
1203
1204                   /* reset visited flag */
1205                   for (j = 0; j < count; ebbs[j++]->visited = 0);
1206
1207                   /* find out if this definition is alive */
1208                   if (applyToSet (ebbs[i]->succList,
1209                                   isDefAlive,
1210                                   ic))
1211                     continue;
1212
1213                   kill = 1;
1214                 }
1215
1216             kill:
1217               /* kill this one if required */
1218               if (kill)
1219                 {
1220                   bool volLeft = IS_SYMOP (IC_LEFT (ic))
1221                                  && isOperandVolatile (IC_LEFT (ic), FALSE);
1222                   bool volRight = IS_SYMOP (IC_RIGHT (ic))
1223                                   && isOperandVolatile (IC_RIGHT (ic), FALSE);
1224
1225                   /* a dead address-of operation should die, even if volatile */
1226                   if (ic->op == ADDRESS_OF)
1227                     volLeft = FALSE;
1228
1229                   if (ic->next && ic->seqPoint == ic->next->seqPoint
1230                       && (ic->next->op == '+' || ic->next->op == '-'))
1231                     {
1232                       if (isOperandEqual (IC_LEFT(ic), IC_LEFT(ic->next))
1233                           || isOperandEqual (IC_LEFT(ic), IC_RIGHT(ic->next)))
1234                         volLeft = FALSE;
1235                       if (isOperandEqual (IC_RIGHT(ic), IC_LEFT(ic->next))
1236                           || isOperandEqual (IC_RIGHT(ic), IC_RIGHT(ic->next)))
1237                         volRight = FALSE;
1238                     }
1239
1240                   if (POINTER_GET (ic) && IS_VOLATILE (operandType (IC_LEFT (ic))->next))
1241                     {
1242                       if (SPIL_LOC (IC_RESULT (ic)))
1243                         {
1244                           IC_RESULT (ic) = newiTempFromOp (IC_RESULT (ic));
1245                           SPIL_LOC (IC_RESULT (ic)) = NULL;
1246                         }
1247                       continue;
1248                     }
1249
1250                   change = 1;
1251                   gchange++;
1252
1253                   /* now delete from defUseSet */
1254                   deleteItemIf (&ebbs[i]->outExprs, ifDiCodeIsX, ic);
1255                   bitVectUnSetBit (ebbs[i]->outDefs, ic->key);
1256
1257                   /* and defset of the block */
1258                   bitVectUnSetBit (ebbs[i]->defSet, ic->key);
1259
1260                   /* If this is the last of a register equivalent, */
1261                   /* look for a successor register equivalent. */
1262                   bitVectUnSetBit (OP_DEFS (IC_RESULT (ic)), ic->key);
1263                   if (IS_ITEMP (IC_RESULT (ic))
1264                       && OP_SYMBOL (IC_RESULT (ic))->isreqv
1265                       && bitVectIsZero (OP_DEFS (IC_RESULT (ic))))
1266                     {
1267                       symbol * resultsym = OP_SYMBOL (IC_RESULT (ic));
1268                       symbol * prereqv = resultsym->prereqv;
1269
1270                       if (prereqv && prereqv->reqv && (OP_SYMBOL (prereqv->reqv) == resultsym))
1271                         {
1272                           operand * newreqv;
1273
1274                           IC_RESULT (ic) = NULL;
1275                           newreqv = findReqv (prereqv, ebbs, count);
1276                           if (newreqv)
1277                             {
1278                               prereqv->reqv = newreqv;
1279                             }
1280                         }
1281                     }
1282
1283                   /* delete the result */
1284                   IC_RESULT (ic) = NULL;
1285
1286                   if (volLeft || volRight)
1287                     {
1288                       /* something is volatile, so keep the iCode */
1289                       /* and change the operator instead */
1290                       ic->op = DUMMY_READ_VOLATILE;
1291
1292                       /* keep only the volatile operands */
1293                       if (!volLeft)
1294                         IC_LEFT (ic) = NULL;
1295                       if (!volRight)
1296                         IC_RIGHT (ic) = NULL;
1297                     }
1298                   else
1299                     {
1300                       /* nothing is volatile, eliminate the iCode */
1301                       remiCodeFromeBBlock (ebbs[i], ic);
1302
1303                       /* for the left & right remove the usage */
1304                       if (IS_SYMOP (IC_LEFT (ic)))
1305                         bitVectUnSetBit (OP_USES (IC_LEFT (ic)), ic->key);
1306
1307                       if (IS_SYMOP (IC_RIGHT (ic)))
1308                         bitVectUnSetBit (OP_USES (IC_RIGHT (ic)), ic->key);
1309                     }
1310                 }
1311
1312             }                   /* end of all instructions */
1313
1314           if (!ebbs[i]->sch && !ebbs[i]->noPath)
1315             disconBBlock (ebbs[i], ebbi);
1316
1317         }                       /* end of for all blocks */
1318
1319       if (!change)
1320         break;
1321     }                           /* end of while(1) */
1322
1323   return gchange;
1324 }
1325
1326 /*-----------------------------------------------------------------*/
1327 /* printCyclomatic - prints the cyclomatic information             */
1328 /*-----------------------------------------------------------------*/
1329 static void
1330 printCyclomatic (eBBlock ** ebbs, int count)
1331 {
1332   int nEdges = elementsInSet (graphEdges);
1333   int i, nNodes = 0;
1334
1335   for (i = 0; i < count; i++)
1336     nNodes += (!ebbs[i]->noPath);
1337
1338   /* print the information */
1339   werror (I_CYCLOMATIC, currFunc->name, nEdges, nNodes, nEdges - nNodes + 2);
1340 }
1341
1342 /*-----------------------------------------------------------------*/
1343 /* discardDeadParamReceives - remove any RECEIVE opcodes which     */
1344 /* refer to dead variables.                                        */
1345 /*-----------------------------------------------------------------*/
1346 static void
1347 discardDeadParamReceives (eBBlock ** ebbs, int count)
1348 {
1349   int i;
1350   iCode *ic;
1351   iCode dummyIcode;
1352
1353   for (i = 0; i < count; i++)
1354     {
1355       for (ic = ebbs[i]->sch; ic; ic = ic->next)
1356         {
1357           if (ic->op == RECEIVE)
1358             {
1359               if (IC_RESULT (ic) && OP_SYMBOL (IC_RESULT (ic))
1360                   && !OP_SYMBOL (IC_RESULT (ic))->used)
1361                 {
1362 #if 0
1363                   fprintf (stderr, "discarding dead receive for %s\n",
1364                            OP_SYMBOL (IC_RESULT (ic))->name);
1365 #endif
1366                   dummyIcode.next = ic->next;
1367                   remiCodeFromeBBlock (ebbs[i], ic);
1368                   ic = &dummyIcode;
1369                 }
1370             }
1371         }
1372     }
1373 }
1374
1375 /*-----------------------------------------------------------------*/
1376 /* optimizeCastCast - remove unneeded intermediate casts.          */
1377 /* Integer promotion may cast (un)signed char to int and then      */
1378 /* recast the int to (un)signed long. If the signedness of the     */
1379 /* char and long are the same, the cast can be safely performed in */
1380 /* a single step.                                                  */
1381 /*-----------------------------------------------------------------*/
1382 static void
1383 optimizeCastCast (eBBlock ** ebbs, int count)
1384 {
1385   int i;
1386   iCode *ic;
1387   iCode *uic;
1388   sym_link * type1;
1389   sym_link * type2;
1390   sym_link * type3;
1391   symbol * sym;
1392
1393   for (i = 0; i < count; i++)
1394     {
1395       for (ic = ebbs[i]->sch; ic; ic = ic->next)
1396         {
1397
1398           if (ic->op == CAST && IC_RESULT (ic) && IS_ITEMP (IC_RESULT (ic)))
1399             {
1400               type1 = operandType (IC_RIGHT (ic));
1401               type2 = operandType (IC_RESULT (ic));
1402
1403               /* Look only for a cast from an integer type to an */
1404               /* integer type that has no loss of bits */
1405               if (!IS_INTEGRAL (type1) || !IS_INTEGRAL (type2))
1406                 continue;
1407               if (getSize (type2) < getSize (type1))
1408                 continue;
1409
1410               /* There must be only one use of this first result */
1411               if (bitVectnBitsOn (OP_USES (IC_RESULT (ic))) != 1)
1412                 continue;
1413
1414               /* This use must be a second cast */
1415               uic = hTabItemWithKey (iCodehTab,
1416                         bitVectFirstBit (OP_USES (IC_RESULT (ic))));
1417               if (!uic || uic->op != CAST)
1418                 continue;
1419
1420               /* It must be a cast to another integer type that */
1421               /* has no loss of bits */
1422               type3 = operandType (IC_RESULT (uic));
1423               if (!IS_INTEGRAL (type3))
1424                  continue;
1425               if (getSize (type3) < getSize (type2))
1426                  continue;
1427
1428               /* The signedness between the first and last types */
1429               /* must match */
1430               if (SPEC_USIGN (type3) != SPEC_USIGN (type1))
1431                  continue;
1432
1433               /* Change the first cast to a simple assignment and */
1434               /* let the second cast do all the work */
1435               ic->op = '=';
1436               IC_LEFT (ic) = NULL;
1437               sym = OP_SYMBOL (IC_RESULT (ic));
1438               sym->type = copyLinkChain (type1);
1439               sym->etype = getSpec (sym->type);
1440             }
1441         }
1442     }
1443 }
1444
1445 /*-----------------------------------------------------------------*/
1446 /* eBBlockFromiCode - creates extended basic blocks from iCode     */
1447 /*                    will return an array of eBBlock pointers     */
1448 /*-----------------------------------------------------------------*/
1449 eBBlock **
1450 eBBlockFromiCode (iCode * ic)
1451 {
1452   ebbIndex *ebbi = NULL;
1453   int change = 1;
1454   int lchange = 0;
1455   int kchange = 0;
1456   hTab *loops;
1457
1458   /* if nothing passed then return nothing */
1459   if (!ic)
1460     return NULL;
1461
1462   eBBNum = 0;
1463
1464   /* optimize the chain for labels & gotos
1465      this will eliminate redundant labels and
1466      will change jump to jumps by jumps */
1467   ic = iCodeLabelOptimize (ic);
1468
1469   /* break it down into basic blocks */
1470   ebbi = iCodeBreakDown (ic);
1471
1472   /* hash the iCode keys so that we can quickly index */
1473   /* them in the rest of the optimization steps */
1474   setToNull ((void *) &iCodehTab);
1475   iCodehTab = newHashTable (iCodeKey);
1476   hashiCodeKeys (ebbi->bbOrder, ebbi->count);
1477
1478   /* compute the control flow */
1479   computeControlFlow (ebbi);
1480
1481   /* dumpraw if asked for */
1482   if (options.dump_raw)
1483     dumpEbbsToFileExt (DUMP_RAW0, ebbi);
1484
1485   /* replace the local variables with their
1486      register equivalents : the liveRange computation
1487      along with the register allocation will determine
1488      if it finally stays in the registers */
1489   replaceRegEqv (ebbi);
1490
1491   /* create loop regions */
1492   loops = createLoopRegions (ebbi);
1493
1494   /* dumpraw if asked for */
1495   if (options.dump_raw)
1496     dumpEbbsToFileExt (DUMP_RAW1, ebbi);
1497
1498   optimizeCastCast (ebbi->bbOrder, ebbi->count);
1499
1500   /* do common subexpression elimination for each block */
1501   change = cseAllBlocks (ebbi, FALSE);
1502
1503   /* dumpraw if asked for */
1504   if (options.dump_raw)
1505     dumpEbbsToFileExt (DUMP_CSE, ebbi);
1506
1507   /* compute the data flow */
1508   computeDataFlow (ebbi);
1509
1510   /* dumpraw if asked for */
1511   if (options.dump_raw)
1512     dumpEbbsToFileExt (DUMP_DFLOW, ebbi);
1513
1514   /* global common subexpression elimination  */
1515   if (optimize.global_cse)
1516     {
1517       change += cseAllBlocks (ebbi, FALSE);
1518       if (options.dump_gcse)
1519         dumpEbbsToFileExt (DUMP_GCSE, ebbi);
1520     }
1521   else
1522     {
1523       // compute the dataflow only
1524       assert(cseAllBlocks (ebbi, TRUE)==0);
1525     }
1526   /* kill dead code */
1527   kchange = killDeadCode (ebbi);
1528
1529   if (options.dump_kill)
1530     dumpEbbsToFileExt (DUMP_DEADCODE, ebbi);
1531
1532   /* do loop optimizations */
1533   change += (lchange = loopOptimizations (loops, ebbi));
1534   if (options.dump_loop)
1535     dumpEbbsToFileExt (DUMP_LOOP, ebbi);
1536
1537   /* recompute the data flow and apply global cse again
1538      if loops optimizations or dead code caused a change:
1539      loops will brings out of the loop which then may be
1540      available for use in the later blocks: dead code
1541      elimination could potentially disconnect some blocks
1542      conditional flow may be efected so we need to apply
1543      subexpression once more */
1544   if (lchange || kchange)
1545     {
1546       computeDataFlow (ebbi);
1547       change += cseAllBlocks (ebbi, FALSE);
1548       if (options.dump_loop)
1549         dumpEbbsToFileExt (DUMP_LOOPG, ebbi);
1550
1551       /* if loop optimizations caused a change then do
1552          dead code elimination once more : this will
1553          get rid of the extra assignments to the induction
1554          variables created during loop optimizations */
1555       killDeadCode (ebbi);
1556
1557       if (options.dump_loop)
1558         dumpEbbsToFileExt (DUMP_LOOPD, ebbi);
1559
1560     }
1561
1562   /* sort it back by block number */
1563   //qsort (ebbs, saveCount, sizeof (eBBlock *), bbNumCompare);
1564
1565   if (!options.lessPedantic) {
1566     // this is a good place to check missing return values
1567     if (currFunc) {
1568       // the user is on his own with naked functions...
1569       if (!IS_VOID(currFunc->etype)
1570        && !FUNC_ISNAKED(currFunc->type)) {
1571         eBBlock *bp;
1572         // make sure all predecessors of the last block end in a return
1573         for (bp=setFirstItem(ebbi->bbOrder[ebbi->count-1]->predList);
1574              bp;
1575              bp=setNextItem(ebbi->bbOrder[ebbi->count-1]->predList)) {
1576           if (bp->ech->op != RETURN) {
1577             werrorfl (bp->ech->filename, bp->ech->lineno,
1578                       W_VOID_FUNC, currFunc->name);
1579           }
1580         }
1581       }
1582     }
1583   }
1584
1585   /* if cyclomatic info requested then print it */
1586   if (options.cyclomatic)
1587     printCyclomatic (ebbi->bbOrder, ebbi->count);
1588
1589   /* convert operations with support routines
1590      written in C to function calls : I am doing
1591      this at this point since I want all the
1592      operations to be as they are for optimizations */
1593   convertToFcall (ebbi->bbOrder, ebbi->count);
1594
1595   /* compute the live ranges */
1596   computeLiveRanges (ebbi->bbOrder, ebbi->count, TRUE);
1597
1598   if (options.dump_range)
1599     dumpEbbsToFileExt (DUMP_RANGE, ebbi);
1600
1601   /* Now that we have the live ranges, discard parameter
1602    * receives for unused parameters.
1603    */
1604   discardDeadParamReceives (ebbi->bbOrder, ebbi->count);
1605
1606   /* allocate registers & generate code */
1607   port->assignRegisters (ebbi);
1608
1609   /* throw away blocks */
1610   setToNull ((void *) &graphEdges);
1611
1612   return NULL;
1613 }
1614
1615
1616 /* (add-hook 'c-mode-hook (lambda () (setq c-basic-offset 4))) */