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