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