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
8 Written By - Sandeep Dutta . sandeep.dutta@usa.net (1998)
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
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.
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.
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 -------------------------------------------------------------------------*/
32 /*-----------------------------------------------------------------*/
33 /* global variables */
39 /*-----------------------------------------------------------------*/
40 /* printSymName - prints the symbol names */
41 /*-----------------------------------------------------------------*/
43 printSymName (void *vsym)
46 fprintf (stdout, " %s ", sym->name);
50 /*-----------------------------------------------------------------*/
51 /* cnvToFcall - does the actual conversion to function call */
52 /*-----------------------------------------------------------------*/
54 cnvToFcall (iCode * ic, eBBlock * ebp)
61 int lineno = ic->lineno;
64 ip = ic->next; /* insertion point */
65 /* remove it from the iCode */
66 remiCodeFromeBBlock (ebp, ic);
69 right = IC_RIGHT (ic);
71 if(IS_FLOAT(operandType( IC_RIGHT( ic ) ))) {
106 if(IS_FIXED16X16 (operandType (IC_RIGHT(ic)))) {
110 func = __fps16x16_add;
113 func = __fps16x16_sub;
116 func = __fps16x16_div;
119 func = __fps16x16_mul;
122 func = __fps16x16_eq;
125 func = __fps16x16_neq;
128 func = __fps16x16_lt;
131 func = __fps16x16_gt;
134 func = __fps16x16_lteq;
137 func = __fps16x16_gteq;
143 /* if float support routines NOT compiled as reentrant */
144 if (!options.float_rent)
148 if (IS_REGPARM (FUNC_ARGS(func->type)->etype))
150 newic = newiCode (SEND, IC_LEFT (ic), NULL);
151 newic->argreg = SPEC_ARGREG(FUNC_ARGS(func->type)->etype);
155 newic = newiCode ('=', NULL, IC_LEFT (ic));
156 IC_RESULT (newic) = operandFromValue (FUNC_ARGS(func->type));
159 addiCodeToeBBlock (ebp, newic, ip);
160 newic->lineno = lineno;
163 if (IS_REGPARM (FUNC_ARGS(func->type)->next->etype))
165 newic = newiCode (SEND, IC_RIGHT (ic), NULL);
166 newic->argreg = SPEC_ARGREG(FUNC_ARGS(func->type)->next->etype);
170 newic = newiCode ('=', NULL, IC_RIGHT (ic));
171 IC_RESULT (newic) = operandFromValue (FUNC_ARGS(func->type)->next);
173 addiCodeToeBBlock (ebp, newic, ip);
174 newic->lineno = lineno;
181 if (IS_REGPARM (FUNC_ARGS(func->type)->next->etype))
183 newic = newiCode (SEND, right, NULL);
184 newic->argreg = SPEC_ARGREG(FUNC_ARGS(func->type)->next->etype);
188 newic = newiCode (IPUSH, right, NULL);
191 bytesPushed += getSize(operandType(right));
194 addiCodeToeBBlock (ebp, newic, ip);
195 newic->lineno = lineno;
197 /* insert push left */
198 if (IS_REGPARM (FUNC_ARGS(func->type)->etype))
200 newic = newiCode (SEND, left, NULL);
201 newic->argreg = SPEC_ARGREG(FUNC_ARGS(func->type)->etype);
205 newic = newiCode (IPUSH, left, NULL);
208 bytesPushed += getSize(operandType(left));
210 addiCodeToeBBlock (ebp, newic, ip);
211 newic->lineno = lineno;
213 /* insert the call */
214 newic = newiCode (CALL, operandFromSymbol (func), NULL);
215 IC_RESULT (newic) = IC_RESULT (ic);
216 newic->lineno = lineno;
217 newic->parmBytes+=bytesPushed;
220 FUNC_HASFCALL (currFunc->type) = 1;
222 if(TARGET_IS_PIC16 || TARGET_IS_PIC) {
223 /* normally these functions aren't marked external, so we can use their
224 * _extern field to marked as already added to symbol table */
226 if(!SPEC_EXTR(func->etype)) {
227 memmap *seg = SPEC_OCLS(OP_SYMBOL(IC_LEFT(newic))->etype);
229 SPEC_EXTR(func->etype) = 1;
230 seg = SPEC_OCLS( func->etype );
231 addSet(&seg->syms, func);
235 addiCodeToeBBlock (ebp, newic, ip);
238 /*-----------------------------------------------------------------*/
239 /* cnvToFloatCast - converts casts to floats to function calls */
240 /*-----------------------------------------------------------------*/
242 cnvToFloatCast (iCode * ic, eBBlock * ebp)
246 sym_link *type = operandType (IC_RIGHT (ic));
247 int linenno = ic->lineno;
252 /* remove it from the iCode */
253 remiCodeFromeBBlock (ebp, ic);
254 /* depending on the type */
255 for (bwd = 0; bwd < 3; bwd++)
257 for (su = 0; su < 2; su++)
259 if (compareType (type, __multypes[bwd][su]) == 1)
261 func = __conv[0][bwd][su];
267 if(compareType (type, fixed16x16Type) == 1) {
268 func = __fp16x16conv[0][3][0];
275 /* if float support routines NOT compiled as reentrant */
276 if (!options.float_rent)
279 if (IS_REGPARM (FUNC_ARGS(func->type)->etype))
281 newic = newiCode (SEND, IC_RIGHT (ic), NULL);
282 newic->argreg = SPEC_ARGREG(FUNC_ARGS(func->type)->etype);
286 newic = newiCode ('=', NULL, IC_RIGHT (ic));
287 IC_RESULT (newic) = operandFromValue (FUNC_ARGS(func->type));
289 addiCodeToeBBlock (ebp, newic, ip);
290 newic->lineno = linenno;
296 if (IS_REGPARM (FUNC_ARGS(func->type)->etype)) {
297 newic = newiCode (SEND, IC_RIGHT (ic), NULL);
298 newic->argreg = SPEC_ARGREG(FUNC_ARGS(func->type)->etype);
302 newic = newiCode (IPUSH, IC_RIGHT (ic), NULL);
304 bytesPushed += getSize(operandType(IC_RIGHT(ic)));
306 addiCodeToeBBlock (ebp, newic, ip);
307 newic->lineno = linenno;
312 newic = newiCode (CALL, operandFromSymbol (func), NULL);
313 IC_RESULT (newic) = IC_RESULT (ic);
314 newic->parmBytes+=bytesPushed;
317 FUNC_HASFCALL (currFunc->type) = 1;
319 if(TARGET_IS_PIC16 || TARGET_IS_PIC) {
320 /* normally these functions aren't marked external, so we can use their
321 * _extern field to marked as already added to symbol table */
323 if(!SPEC_EXTR(func->etype)) {
324 memmap *seg = SPEC_OCLS(OP_SYMBOL(IC_LEFT(newic))->etype);
326 SPEC_EXTR(func->etype) = 1;
327 seg = SPEC_OCLS( func->etype );
328 addSet(&seg->syms, func);
332 addiCodeToeBBlock (ebp, newic, ip);
333 newic->lineno = linenno;
336 /*----------------------------------------------------------------------*/
337 /* cnvToFixed16x16Cast - converts casts to fixed16x16 to function calls */
338 /*----------------------------------------------------------------------*/
340 cnvToFixed16x16Cast (iCode * ic, eBBlock * ebp)
344 sym_link *type = operandType (IC_RIGHT (ic));
345 int linenno = ic->lineno;
350 /* remove it from the iCode */
351 remiCodeFromeBBlock (ebp, ic);
352 /* depending on the type */
353 for (bwd = 0; bwd < 3; bwd++)
355 for (su = 0; su < 2; su++)
357 if (compareType (type, __multypes[bwd][su]) == 1)
359 func = __fp16x16conv[0][bwd][su];
367 /* if float support routines NOT compiled as reentrant */
368 if (!options.float_rent)
371 if (IS_REGPARM (FUNC_ARGS(func->type)->etype))
373 newic = newiCode (SEND, IC_RIGHT (ic), NULL);
374 newic->argreg = SPEC_ARGREG(FUNC_ARGS(func->type)->etype);
378 newic = newiCode ('=', NULL, IC_RIGHT (ic));
379 IC_RESULT (newic) = operandFromValue (FUNC_ARGS(func->type));
381 addiCodeToeBBlock (ebp, newic, ip);
382 newic->lineno = linenno;
388 if (IS_REGPARM (FUNC_ARGS(func->type)->etype)) {
389 newic = newiCode (SEND, IC_RIGHT (ic), NULL);
390 newic->argreg = SPEC_ARGREG(FUNC_ARGS(func->type)->etype);
394 newic = newiCode (IPUSH, IC_RIGHT (ic), NULL);
396 bytesPushed += getSize(operandType(IC_RIGHT(ic)));
398 addiCodeToeBBlock (ebp, newic, ip);
399 newic->lineno = linenno;
404 newic = newiCode (CALL, operandFromSymbol (func), NULL);
405 IC_RESULT (newic) = IC_RESULT (ic);
406 newic->parmBytes+=bytesPushed;
409 FUNC_HASFCALL (currFunc->type) = 1;
411 if(TARGET_IS_PIC16 || TARGET_IS_PIC) {
412 /* normally these functions aren't marked external, so we can use their
413 * _extern field to marked as already added to symbol table */
415 if(!SPEC_EXTR(func->etype)) {
416 memmap *seg = SPEC_OCLS(OP_SYMBOL(IC_LEFT(newic))->etype);
418 SPEC_EXTR(func->etype) = 1;
419 seg = SPEC_OCLS( func->etype );
420 addSet(&seg->syms, func);
424 addiCodeToeBBlock (ebp, newic, ip);
425 newic->lineno = linenno;
428 /*-----------------------------------------------------------------*/
429 /* cnvFromFloatCast - converts casts From floats to function calls */
430 /*-----------------------------------------------------------------*/
432 cnvFromFloatCast (iCode * ic, eBBlock * ebp)
436 sym_link *type = operandType (IC_LEFT (ic));
437 int lineno = ic->lineno;
442 /* remove it from the iCode */
443 remiCodeFromeBBlock (ebp, ic);
445 /* depending on the type */
446 for (bwd = 0; bwd < 3; bwd++)
448 for (su = 0; su < 2; su++)
450 if (compareType (type, __multypes[bwd][su]) == 1)
452 func = __conv[1][bwd][su];
460 /* if float support routines NOT compiled as reentrant */
461 if (!options.float_rent)
464 if (IS_REGPARM (FUNC_ARGS(func->type)->etype)) {
465 newic = newiCode (SEND, IC_RIGHT (ic), NULL);
466 newic->argreg = SPEC_ARGREG(FUNC_ARGS(func->type)->etype);
470 newic = newiCode ('=', NULL, IC_RIGHT (ic));
471 IC_RESULT (newic) = operandFromValue (FUNC_ARGS(func->type));
473 addiCodeToeBBlock (ebp, newic, ip);
474 newic->lineno = lineno;
481 if (IS_REGPARM (FUNC_ARGS(func->type)->etype)) {
482 newic = newiCode (SEND, IC_RIGHT (ic), NULL);
483 newic->argreg = SPEC_ARGREG(FUNC_ARGS(func->type)->etype);
487 newic = newiCode (IPUSH, IC_RIGHT (ic), NULL);
489 bytesPushed += getSize(operandType(IC_RIGHT(ic)));
491 addiCodeToeBBlock (ebp, newic, ip);
492 newic->lineno = lineno;
497 newic = newiCode (CALL, operandFromSymbol (func), NULL);
498 IC_RESULT (newic) = IC_RESULT (ic);
499 newic->parmBytes+=bytesPushed;
502 FUNC_HASFCALL (currFunc->type) = 1;
504 if(TARGET_IS_PIC16 || TARGET_IS_PIC) {
505 /* normally these functions aren't marked external, so we can use their
506 * _extern field to marked as already added to symbol table */
508 if(!SPEC_EXTR(func->etype)) {
509 memmap *seg = SPEC_OCLS(OP_SYMBOL(IC_LEFT(newic))->etype);
511 SPEC_EXTR(func->etype) = 1;
512 seg = SPEC_OCLS( func->etype );
513 addSet(&seg->syms, func);
517 addiCodeToeBBlock (ebp, newic, ip);
518 newic->lineno = lineno;
521 /*--------------------------------------------------------------------------*/
522 /* cnvFromFixed16x16Cast - converts casts from fixed16x16 to function calls */
523 /*--------------------------------------------------------------------------*/
525 cnvFromFixed16x16Cast (iCode * ic, eBBlock * ebp)
529 sym_link *type = operandType (IC_LEFT (ic));
530 int lineno = ic->lineno;
535 /* remove it from the iCode */
536 remiCodeFromeBBlock (ebp, ic);
538 /* depending on the type */
539 for (bwd = 0; bwd < 3; bwd++)
541 for (su = 0; su < 2; su++)
543 if (compareType (type, __multypes[bwd][su]) == 1)
545 func = __fp16x16conv[1][bwd][su];
551 if (compareType (type, floatType) == 1)
553 func = __fp16x16conv[1][3][0];
560 /* if float support routines NOT compiled as reentrant */
561 if (!options.float_rent)
564 if (IS_REGPARM (FUNC_ARGS(func->type)->etype)) {
565 newic = newiCode (SEND, IC_RIGHT (ic), NULL);
566 newic->argreg = SPEC_ARGREG(FUNC_ARGS(func->type)->etype);
570 newic = newiCode ('=', NULL, IC_RIGHT (ic));
571 IC_RESULT (newic) = operandFromValue (FUNC_ARGS(func->type));
573 addiCodeToeBBlock (ebp, newic, ip);
574 newic->lineno = lineno;
581 if (IS_REGPARM (FUNC_ARGS(func->type)->etype)) {
582 newic = newiCode (SEND, IC_RIGHT (ic), NULL);
583 newic->argreg = SPEC_ARGREG(FUNC_ARGS(func->type)->etype);
587 newic = newiCode (IPUSH, IC_RIGHT (ic), NULL);
589 bytesPushed += getSize(operandType(IC_RIGHT(ic)));
591 addiCodeToeBBlock (ebp, newic, ip);
592 newic->lineno = lineno;
597 newic = newiCode (CALL, operandFromSymbol (func), NULL);
598 IC_RESULT (newic) = IC_RESULT (ic);
599 newic->parmBytes+=bytesPushed;
602 FUNC_HASFCALL (currFunc->type) = 1;
604 if(TARGET_IS_PIC16 || TARGET_IS_PIC) {
605 /* normally these functions aren't marked external, so we can use their
606 * _extern field to marked as already added to symbol table */
608 if(!SPEC_EXTR(func->etype)) {
609 memmap *seg = SPEC_OCLS(OP_SYMBOL(IC_LEFT(newic))->etype);
611 SPEC_EXTR(func->etype) = 1;
612 seg = SPEC_OCLS( func->etype );
613 addSet(&seg->syms, func);
617 addiCodeToeBBlock (ebp, newic, ip);
618 newic->lineno = lineno;
621 extern operand *geniCodeRValue (operand *, bool);
623 /*-----------------------------------------------------------------*/
624 /* convilong - converts int or long mults or divs to fcalls */
625 /*-----------------------------------------------------------------*/
627 convilong (iCode * ic, eBBlock * ebp, sym_link * type, int op)
630 iCode *ip = ic->next;
632 int lineno = ic->lineno;
637 remiCodeFromeBBlock (ebp, ic);
639 /* depending on the type */
640 for (bwd = 0; bwd < 3; bwd++)
642 for (su = 0; su < 2; su++)
644 if (compareType (type, __multypes[bwd][su]) == 1)
647 func = __muldiv[0][bwd][su];
649 func = __muldiv[1][bwd][su];
651 func = __muldiv[2][bwd][su];
653 func = __rlrr[1][bwd][su];
655 func = __rlrr[0][bwd][su];
656 else if (op == RIGHT_OP)
657 func = __rlrr[1][bwd][su];
658 else if (op == LEFT_OP)
659 func = __rlrr[0][bwd][su];
668 /* if int & long support routines NOT compiled as reentrant */
669 if (!options.intlong_rent)
672 if (IS_REGPARM (FUNC_ARGS(func->type)->etype)) {
673 newic = newiCode (SEND, IC_LEFT (ic), NULL);
674 newic->argreg = SPEC_ARGREG(FUNC_ARGS(func->type)->etype);
678 newic = newiCode ('=', NULL, IC_LEFT (ic));
679 IC_RESULT (newic) = operandFromValue (FUNC_ARGS(func->type));
681 addiCodeToeBBlock (ebp, newic, ip);
682 newic->lineno = lineno;
685 if (IS_REGPARM (FUNC_ARGS(func->type)->next->etype)) {
686 newic = newiCode (SEND, IC_RIGHT (ic), NULL);
687 newic->argreg = SPEC_ARGREG(FUNC_ARGS(func->type)->next->etype);
691 newic = newiCode ('=', NULL, IC_RIGHT (ic));
692 IC_RESULT (newic) = operandFromValue (FUNC_ARGS(func->type)->next);
694 addiCodeToeBBlock (ebp, newic, ip);
695 newic->lineno = lineno;
700 /* compiled as reentrant then push */
702 if (IS_REGPARM (FUNC_ARGS(func->type)->next->etype))
704 newic = newiCode (SEND, IC_RIGHT (ic), NULL);
705 newic->argreg = SPEC_ARGREG(FUNC_ARGS(func->type)->next->etype);
709 newic = newiCode (IPUSH, IC_RIGHT (ic), NULL);
712 bytesPushed += getSize(operandType(IC_RIGHT(ic)));
714 addiCodeToeBBlock (ebp, newic, ip);
715 newic->lineno = lineno;
717 /* insert push left */
718 if (IS_REGPARM (FUNC_ARGS(func->type)->etype))
720 newic = newiCode (SEND, IC_LEFT (ic), NULL);
721 newic->argreg = SPEC_ARGREG(FUNC_ARGS(func->type)->etype);
725 newic = newiCode (IPUSH, IC_LEFT (ic), NULL);
728 bytesPushed += getSize(operandType(IC_LEFT(ic)));
730 addiCodeToeBBlock (ebp, newic, ip);
731 newic->lineno = lineno;
736 newic = newiCode (CALL, operandFromSymbol (func), NULL);
737 IC_RESULT (newic) = IC_RESULT (ic);
738 newic->lineno = lineno;
739 newic->parmBytes+=bytesPushed; // to clear the stack after the call
742 FUNC_HASFCALL (currFunc->type) = 1;
744 if(TARGET_IS_PIC || TARGET_IS_PIC16) {
745 /* normally these functions aren't marked external, so we can use their
746 * _extern field to marked as already added to symbol table */
748 if(!SPEC_EXTR(func->etype)) {
749 memmap *seg = SPEC_OCLS(OP_SYMBOL(IC_LEFT(newic))->etype);
751 SPEC_EXTR(func->etype) = 1;
752 seg = SPEC_OCLS( func->etype );
753 addSet(&seg->syms, func);
757 addiCodeToeBBlock (ebp, newic, ip);
760 /*-----------------------------------------------------------------*/
761 /* convertToFcall - converts some operations to fcalls */
762 /*-----------------------------------------------------------------*/
764 convertToFcall (eBBlock ** ebbs, int count)
768 /* for all blocks do */
769 for (i = 0; i < count; i++)
773 /* for all instructions in the block do */
774 for (ic = ebbs[i]->sch; ic; ic = ic->next)
777 /* floating point operations are
778 converted to function calls */
779 if ((IS_CONDITIONAL (ic) ||
780 IS_ARITHMETIC_OP (ic)) &&
781 (IS_FLOAT (operandType (IC_RIGHT (ic))) ||
782 IS_FIXED( operandType (IC_RIGHT (ic)))))
785 cnvToFcall (ic, ebbs[i]);
788 /* casting is a little different */
791 if (IS_FLOAT (operandType (IC_RIGHT (ic))))
792 cnvFromFloatCast (ic, ebbs[i]);
793 else if (IS_FLOAT (operandType (IC_LEFT (ic))))
794 cnvToFloatCast (ic, ebbs[i]);
795 if (IS_FIXED16X16 (operandType (IC_RIGHT (ic))))
796 cnvFromFixed16x16Cast (ic, ebbs[i]);
797 else if (IS_FIXED16X16 (operandType (IC_LEFT (ic))))
798 cnvToFixed16x16Cast (ic, ebbs[i]);
801 // Easy special case which avoids function call: modulo by a literal power
802 // of two can be replaced by a bitwise AND.
803 if (ic->op == '%' && isOperandLiteral(IC_RIGHT(ic)) &&
804 IS_UNSIGNED(operandType(IC_LEFT(ic))))
806 unsigned litVal = abs((unsigned)operandLitValue(IC_RIGHT(ic)));
808 /* modulo by 1: no remainder */
812 IC_RIGHT (ic) = operandFromLit(0);
816 // See if literal value is a power of 2.
817 while (litVal && !(litVal & 1))
823 // discard lowest set bit.
830 IC_RIGHT(ic) = operandFromLit(operandLitValue(IC_RIGHT(ic)) - 1);
835 /* if long / int mult or divide or mod */
836 if (ic->op == '*' || ic->op == '/' || ic->op == '%')
838 sym_link *leftType = operandType (IC_LEFT (ic));
840 if (IS_INTEGRAL (leftType) && getSize (leftType) > port->support.muldiv)
842 sym_link *rightType = operandType (IC_RIGHT (ic));
844 if (port->hasNativeMulFor != NULL &&
845 port->hasNativeMulFor (ic, leftType, rightType))
847 /* Leave as native */
851 convilong (ic, ebbs[i], leftType, ic->op);
856 if (ic->op == RRC || ic->op == RLC || ic->op == LEFT_OP || ic->op == RIGHT_OP)
858 sym_link *type = operandType (IC_LEFT (ic));
860 if (IS_INTEGRAL (type) && getSize (type) > port->support.shift && port->support.shift >= 0)
862 convilong (ic, ebbs[i], type, ic->op);
869 /*-----------------------------------------------------------------*/
870 /* isLocalWithoutDef - return 1 if sym might be used without a */
872 /*-----------------------------------------------------------------*/
874 isLocalWithoutDef (symbol * sym)
879 if (IS_VOLATILE (sym->type))
885 if (IS_AGGREGATE (sym->type))
894 /*-----------------------------------------------------------------*/
895 /* replaceRegEqv - replace all local variables with their reqv */
896 /*-----------------------------------------------------------------*/
898 replaceRegEqv (ebbIndex * ebbi)
900 eBBlock ** ebbs = ebbi->bbOrder;
901 int count = ebbi->count;
904 /* Update the symbols' def bitvector so we know if there is */
905 /* a defining iCode or not. Only replace a local variable */
906 /* with its register equivalent if there is a defining iCode; */
907 /* otherwise, the port's register allocater may choke. */
908 cseAllBlocks (ebbi, TRUE);
910 for (i = 0; i < count; i++)
915 for (ic = ebbs[i]->sch; ic; ic = ic->next)
924 IS_TRUE_SYMOP (IC_COND (ic)) &&
925 isLocalWithoutDef (OP_SYMBOL (IC_COND (ic))))
927 werrorfl (ic->filename, ic->lineno,
929 OP_SYMBOL (IC_COND (ic))->name);
930 OP_REQV (IC_COND (ic)) = NULL;
931 OP_SYMBOL (IC_COND (ic))->allocreq = 1;
934 if (IS_TRUE_SYMOP (IC_COND (ic)) &&
935 OP_REQV (IC_COND (ic)))
936 IC_COND (ic) = opFromOpWithDU (OP_REQV (IC_COND (ic)),
937 OP_SYMBOL (IC_COND (ic))->defs,
938 OP_SYMBOL (IC_COND (ic))->uses);
944 if (ic->op == JUMPTABLE)
946 if (IC_JTCOND (ic) &&
947 IS_TRUE_SYMOP (IC_JTCOND (ic)) &&
948 isLocalWithoutDef (OP_SYMBOL (IC_JTCOND (ic))))
950 werrorfl (ic->filename, ic->lineno,
952 OP_SYMBOL (IC_JTCOND (ic))->name);
953 OP_REQV (IC_JTCOND (ic)) = NULL;
954 OP_SYMBOL (IC_JTCOND (ic))->allocreq = 1;
957 if (IS_TRUE_SYMOP (IC_JTCOND (ic)) &&
958 OP_REQV (IC_JTCOND (ic)))
959 IC_JTCOND (ic) = opFromOpWithDU (OP_REQV (IC_JTCOND (ic)),
960 OP_SYMBOL (IC_JTCOND (ic))->defs,
961 OP_SYMBOL (IC_JTCOND (ic))->uses);
965 if (ic->op == RECEIVE)
967 if (OP_SYMBOL (IC_RESULT (ic))->addrtaken)
968 OP_SYMBOL (IC_RESULT (ic))->isspilt = 1;
972 if (IC_RESULT (ic) &&
973 IS_TRUE_SYMOP (IC_RESULT (ic)) &&
974 OP_REQV (IC_RESULT (ic)))
976 if (POINTER_SET (ic))
978 IC_RESULT (ic) = opFromOpWithDU (OP_REQV (IC_RESULT (ic)),
979 OP_SYMBOL (IC_RESULT (ic))->defs,
980 OP_SYMBOL (IC_RESULT (ic))->uses);
981 IC_RESULT (ic)->isaddr = 1;
984 IC_RESULT (ic) = opFromOpWithDU (OP_REQV (IC_RESULT (ic)),
985 OP_SYMBOL (IC_RESULT (ic))->defs,
986 OP_SYMBOL (IC_RESULT (ic))->uses);
990 IS_TRUE_SYMOP (IC_RIGHT (ic)) &&
991 isLocalWithoutDef (OP_SYMBOL (IC_RIGHT (ic))))
993 werrorfl (ic->filename, ic->lineno,
995 OP_SYMBOL (IC_RIGHT (ic))->name);
996 OP_REQV (IC_RIGHT (ic)) = NULL;
997 OP_SYMBOL (IC_RIGHT (ic))->allocreq = 1;
1000 if (IC_RIGHT (ic) &&
1001 IS_TRUE_SYMOP (IC_RIGHT (ic)) &&
1002 OP_REQV (IC_RIGHT (ic)))
1004 IC_RIGHT (ic) = opFromOpWithDU (OP_REQV (IC_RIGHT (ic)),
1005 OP_SYMBOL (IC_RIGHT (ic))->defs,
1006 OP_SYMBOL (IC_RIGHT (ic))->uses);
1007 IC_RIGHT (ic)->isaddr = 0;
1011 IS_TRUE_SYMOP (IC_LEFT (ic)) &&
1012 isLocalWithoutDef (OP_SYMBOL (IC_LEFT (ic))))
1014 werrorfl (ic->filename, ic->lineno,
1016 OP_SYMBOL (IC_LEFT (ic))->name);
1017 OP_REQV (IC_LEFT (ic)) = NULL;
1018 OP_SYMBOL (IC_LEFT (ic))->allocreq = 1;
1022 IS_TRUE_SYMOP (IC_LEFT (ic)) &&
1023 OP_REQV (IC_LEFT (ic)))
1025 IC_LEFT (ic) = opFromOpWithDU (OP_REQV (IC_LEFT (ic)),
1026 OP_SYMBOL (IC_LEFT (ic))->defs,
1027 OP_SYMBOL (IC_LEFT (ic))->uses);
1028 IC_LEFT (ic)->isaddr = 0;
1034 /*-----------------------------------------------------------------*/
1035 /* findReqv - search for a register equivalent */
1036 /*-----------------------------------------------------------------*/
1038 findReqv (symbol * prereqv, eBBlock ** ebbs, int count)
1043 /* for all blocks do */
1044 for (i=0; i<count; i++)
1046 /* for all instructions in the block do */
1047 for (ic = ebbs[i]->sch; ic; ic = ic->next)
1051 if (IS_ITEMP (IC_COND (ic))
1052 && OP_SYMBOL (IC_COND (ic))->prereqv == prereqv)
1053 return IC_COND (ic);
1055 else if (ic->op == JUMPTABLE)
1057 if (IS_ITEMP (IC_JTCOND (ic))
1058 && OP_SYMBOL (IC_JTCOND (ic))->prereqv == prereqv)
1059 return IC_JTCOND (ic);
1063 if (IS_ITEMP (IC_LEFT (ic))
1064 && OP_SYMBOL (IC_LEFT (ic))->prereqv == prereqv)
1065 return IC_LEFT (ic);
1066 if (IS_ITEMP (IC_RIGHT (ic))
1067 && OP_SYMBOL (IC_RIGHT (ic))->prereqv == prereqv)
1068 return IC_RIGHT (ic);
1069 if (IS_ITEMP (IC_RESULT (ic))
1070 && OP_SYMBOL (IC_RESULT (ic))->prereqv == prereqv)
1071 return IC_RESULT (ic);
1079 /*-----------------------------------------------------------------*/
1080 /* killDeadCode - eliminates dead assignments */
1081 /*-----------------------------------------------------------------*/
1083 killDeadCode (ebbIndex * ebbi)
1085 eBBlock ** ebbs = ebbi->dfOrder;
1086 int count = ebbi->count;
1092 /* basic algorithm :- */
1093 /* first the exclusion rules :- */
1094 /* 1. if result is a global or volatile then skip */
1095 /* 2. if assignment and result is a temp & isaddr then skip */
1096 /* since this means array & pointer access, will be taken */
1097 /* care of by alias analysis. */
1098 /* 3. if the result is used in the remainder of the block skip */
1099 /* 4. if this definition does not reach the end of the block */
1100 /* i.e. the result is not present in the outExprs then KILL */
1101 /* 5. if it reaches the end of block & is used by some success */
1104 /* this whole process is carried on iteratively till no change */
1109 /* for all blocks do */
1110 for (i = 0; i < count; i++)
1114 /* for all instructions in the block do */
1115 for (ic = ebbs[i]->sch; ic; ic = ic->next)
1123 ic->op == DUMMY_READ_VOLATILE ||
1124 ic->op == CRITICAL ||
1125 ic->op == ENDCRITICAL)
1128 /* Since both IFX & JUMPTABLE (in SKIP_IC) have been tested for */
1129 /* it is now safe to assume IC_LEFT, IC_RIGHT, & IC_RESULT are */
1132 /* if the result is volatile then continue */
1133 if (IC_RESULT (ic) && isOperandVolatile (IC_RESULT (ic), FALSE))
1136 /* if the result is a temp & isaddr then skip */
1137 if (IC_RESULT (ic) && POINTER_SET (ic))
1140 if (POINTER_GET (ic) && IS_VOLATILE (operandType (IC_LEFT (ic))->next)
1141 && !SPIL_LOC (IC_RESULT (ic)))
1144 /* if the result is used in the remainder of the */
1145 /* block then skip */
1146 if (usedInRemaining (IC_RESULT (ic), ic->next))
1149 /* does this definition reach the end of the block
1150 or the usage is zero then we can kill */
1151 if (!bitVectBitValue (ebbs[i]->outDefs, ic->key))
1152 kill = 1; /* if not we can kill it */
1155 /* if this is a global variable or function parameter */
1156 /* we cannot kill anyway */
1157 if (isOperandGlobal (IC_RESULT (ic)) ||
1158 (OP_SYMBOL (IC_RESULT (ic))->_isparm &&
1159 !OP_SYMBOL (IC_RESULT (ic))->ismyparm))
1162 /* if we are sure there are no usages */
1163 if (bitVectIsZero (OP_USES (IC_RESULT (ic))))
1169 /* reset visited flag */
1170 for (j = 0; j < count; ebbs[j++]->visited = 0);
1172 /* find out if this definition is alive */
1173 if (applyToSet (ebbs[i]->succList,
1182 /* kill this one if required */
1185 bool volLeft = IS_SYMOP (IC_LEFT (ic))
1186 && isOperandVolatile (IC_LEFT (ic), FALSE);
1187 bool volRight = IS_SYMOP (IC_RIGHT (ic))
1188 && isOperandVolatile (IC_RIGHT (ic), FALSE);
1190 /* a dead address-of operation should die, even if volatile */
1191 if (ic->op == ADDRESS_OF)
1194 if (ic->next && ic->seqPoint == ic->next->seqPoint
1195 && (ic->next->op == '+' || ic->next->op == '-'))
1197 if (isOperandEqual (IC_LEFT(ic), IC_LEFT(ic->next))
1198 || isOperandEqual (IC_LEFT(ic), IC_RIGHT(ic->next)))
1200 if (isOperandEqual (IC_RIGHT(ic), IC_LEFT(ic->next))
1201 || isOperandEqual (IC_RIGHT(ic), IC_RIGHT(ic->next)))
1205 if (POINTER_GET (ic) && IS_VOLATILE (operandType (IC_LEFT (ic))->next))
1207 if (SPIL_LOC (IC_RESULT (ic)))
1209 IC_RESULT (ic) = newiTempFromOp (IC_RESULT (ic));
1210 SPIL_LOC (IC_RESULT (ic)) = NULL;
1218 /* now delete from defUseSet */
1219 deleteItemIf (&ebbs[i]->outExprs, ifDiCodeIsX, ic);
1220 bitVectUnSetBit (ebbs[i]->outDefs, ic->key);
1222 /* and defset of the block */
1223 bitVectUnSetBit (ebbs[i]->defSet, ic->key);
1225 /* If this is the last of a register equivalent, */
1226 /* look for a successor register equivalent. */
1227 bitVectUnSetBit (OP_DEFS (IC_RESULT (ic)), ic->key);
1228 if (IS_ITEMP (IC_RESULT (ic))
1229 && OP_SYMBOL (IC_RESULT (ic))->isreqv
1230 && bitVectIsZero (OP_DEFS (IC_RESULT (ic))))
1232 symbol * resultsym = OP_SYMBOL (IC_RESULT (ic));
1233 symbol * prereqv = resultsym->prereqv;
1235 if (prereqv && prereqv->reqv && (OP_SYMBOL (prereqv->reqv) == resultsym))
1239 IC_RESULT (ic) = NULL;
1240 newreqv = findReqv (prereqv, ebbs, count);
1243 prereqv->reqv = newreqv;
1248 /* delete the result */
1249 IC_RESULT (ic) = NULL;
1251 if (volLeft || volRight)
1253 /* something is volatile, so keep the iCode */
1254 /* and change the operator instead */
1255 ic->op = DUMMY_READ_VOLATILE;
1257 /* keep only the volatile operands */
1259 IC_LEFT (ic) = NULL;
1261 IC_RIGHT (ic) = NULL;
1265 /* nothing is volatile, eliminate the iCode */
1266 remiCodeFromeBBlock (ebbs[i], ic);
1268 /* for the left & right remove the usage */
1269 if (IS_SYMOP (IC_LEFT (ic)))
1270 bitVectUnSetBit (OP_USES (IC_LEFT (ic)), ic->key);
1272 if (IS_SYMOP (IC_RIGHT (ic)))
1273 bitVectUnSetBit (OP_USES (IC_RIGHT (ic)), ic->key);
1277 } /* end of all instructions */
1279 if (!ebbs[i]->sch && !ebbs[i]->noPath)
1280 disconBBlock (ebbs[i], ebbi);
1282 } /* end of for all blocks */
1286 } /* end of while(1) */
1291 /*-----------------------------------------------------------------*/
1292 /* printCyclomatic - prints the cyclomatic information */
1293 /*-----------------------------------------------------------------*/
1295 printCyclomatic (eBBlock ** ebbs, int count)
1297 int nEdges = elementsInSet (graphEdges);
1300 for (i = 0; i < count; i++)
1301 nNodes += (!ebbs[i]->noPath);
1303 /* print the information */
1304 werror (I_CYCLOMATIC, currFunc->name, nEdges, nNodes, nEdges - nNodes + 2);
1307 /*-----------------------------------------------------------------*/
1308 /* discardDeadParamReceives - remove any RECEIVE opcodes which */
1309 /* refer to dead variables. */
1310 /*-----------------------------------------------------------------*/
1312 discardDeadParamReceives (eBBlock ** ebbs, int count)
1318 for (i = 0; i < count; i++)
1320 for (ic = ebbs[i]->sch; ic; ic = ic->next)
1322 if (ic->op == RECEIVE)
1324 if (IC_RESULT (ic) && OP_SYMBOL (IC_RESULT (ic))
1325 && !OP_SYMBOL (IC_RESULT (ic))->used)
1328 fprintf (stderr, "discarding dead receive for %s\n",
1329 OP_SYMBOL (IC_RESULT (ic))->name);
1331 dummyIcode.next = ic->next;
1332 remiCodeFromeBBlock (ebbs[i], ic);
1340 /*-----------------------------------------------------------------*/
1341 /* optimizeCastCast - remove unneeded intermediate casts. */
1342 /* Integer promotion may cast (un)signed char to int and then */
1343 /* recast the int to (un)signed long. If the signedness of the */
1344 /* char and long are the same, the cast can be safely performed in */
1345 /* a single step. */
1346 /*-----------------------------------------------------------------*/
1348 optimizeCastCast (eBBlock ** ebbs, int count)
1358 for (i = 0; i < count; i++)
1360 for (ic = ebbs[i]->sch; ic; ic = ic->next)
1363 if (ic->op == CAST && IC_RESULT (ic) && IS_ITEMP (IC_RESULT (ic)))
1365 type1 = operandType (IC_RIGHT (ic));
1366 type2 = operandType (IC_RESULT (ic));
1368 /* Look only for a cast from an integer type to an */
1369 /* integer type that has no loss of bits */
1370 if (!IS_INTEGRAL (type1) || !IS_INTEGRAL (type2))
1372 if (getSize (type2) < getSize (type1))
1375 /* There must be only one use of this first result */
1376 if (bitVectnBitsOn (OP_USES (IC_RESULT (ic))) != 1)
1379 /* This use must be a second cast */
1380 uic = hTabItemWithKey (iCodehTab,
1381 bitVectFirstBit (OP_USES (IC_RESULT (ic))));
1382 if (!uic || uic->op != CAST)
1385 /* It must be a cast to another integer type that */
1386 /* has no loss of bits */
1387 type3 = operandType (IC_RESULT (uic));
1388 if (!IS_INTEGRAL (type3))
1390 if (getSize (type3) < getSize (type2))
1393 /* The signedness between the first and last types */
1395 if (SPEC_USIGN (type3) != SPEC_USIGN (type1))
1398 /* Change the first cast to a simple assignment and */
1399 /* let the second cast do all the work */
1401 IC_LEFT (ic) = NULL;
1402 sym = OP_SYMBOL (IC_RESULT (ic));
1403 sym->type = copyLinkChain (type1);
1404 sym->etype = getSpec (sym->type);
1410 /*-----------------------------------------------------------------*/
1411 /* eBBlockFromiCode - creates extended basic blocks from iCode */
1412 /* will return an array of eBBlock pointers */
1413 /*-----------------------------------------------------------------*/
1415 eBBlockFromiCode (iCode * ic)
1417 ebbIndex *ebbi = NULL;
1423 /* if nothing passed then return nothing */
1429 /* optimize the chain for labels & gotos
1430 this will eliminate redundant labels and
1431 will change jump to jumps by jumps */
1432 ic = iCodeLabelOptimize (ic);
1434 /* break it down into basic blocks */
1435 ebbi = iCodeBreakDown (ic);
1437 /* hash the iCode keys so that we can quickly index */
1438 /* them in the rest of the optimization steps */
1439 setToNull ((void *) &iCodehTab);
1440 iCodehTab = newHashTable (iCodeKey);
1441 hashiCodeKeys (ebbi->bbOrder, ebbi->count);
1443 /* compute the control flow */
1444 computeControlFlow (ebbi);
1446 /* dumpraw if asked for */
1447 if (options.dump_raw)
1448 dumpEbbsToFileExt (DUMP_RAW0, ebbi);
1450 /* replace the local variables with their
1451 register equivalents : the liveRange computation
1452 along with the register allocation will determine
1453 if it finally stays in the registers */
1454 replaceRegEqv (ebbi);
1456 /* create loop regions */
1457 loops = createLoopRegions (ebbi);
1459 /* dumpraw if asked for */
1460 if (options.dump_raw)
1461 dumpEbbsToFileExt (DUMP_RAW1, ebbi);
1463 optimizeCastCast (ebbi->bbOrder, ebbi->count);
1465 /* do common subexpression elimination for each block */
1466 change = cseAllBlocks (ebbi, FALSE);
1468 /* dumpraw if asked for */
1469 if (options.dump_raw)
1470 dumpEbbsToFileExt (DUMP_CSE, ebbi);
1472 /* compute the data flow */
1473 computeDataFlow (ebbi);
1475 /* dumpraw if asked for */
1476 if (options.dump_raw)
1477 dumpEbbsToFileExt (DUMP_DFLOW, ebbi);
1479 /* global common subexpression elimination */
1480 if (optimize.global_cse)
1482 change += cseAllBlocks (ebbi, FALSE);
1483 if (options.dump_gcse)
1484 dumpEbbsToFileExt (DUMP_GCSE, ebbi);
1488 // compute the dataflow only
1489 assert(cseAllBlocks (ebbi, TRUE)==0);
1491 /* kill dead code */
1492 kchange = killDeadCode (ebbi);
1494 if (options.dump_kill)
1495 dumpEbbsToFileExt (DUMP_DEADCODE, ebbi);
1497 /* do loop optimizations */
1498 change += (lchange = loopOptimizations (loops, ebbi));
1499 if (options.dump_loop)
1500 dumpEbbsToFileExt (DUMP_LOOP, ebbi);
1502 /* recompute the data flow and apply global cse again
1503 if loops optimizations or dead code caused a change:
1504 loops will brings out of the loop which then may be
1505 available for use in the later blocks: dead code
1506 elimination could potentially disconnect some blocks
1507 conditional flow may be efected so we need to apply
1508 subexpression once more */
1509 if (lchange || kchange)
1511 computeDataFlow (ebbi);
1512 change += cseAllBlocks (ebbi, FALSE);
1513 if (options.dump_loop)
1514 dumpEbbsToFileExt (DUMP_LOOPG, ebbi);
1516 /* if loop optimizations caused a change then do
1517 dead code elimination once more : this will
1518 get rid of the extra assignments to the induction
1519 variables created during loop optimizations */
1520 killDeadCode (ebbi);
1522 if (options.dump_loop)
1523 dumpEbbsToFileExt (DUMP_LOOPD, ebbi);
1527 /* sort it back by block number */
1528 //qsort (ebbs, saveCount, sizeof (eBBlock *), bbNumCompare);
1530 if (!options.lessPedantic) {
1531 // this is a good place to check missing return values
1533 // the user is on his own with naked functions...
1534 if (!IS_VOID(currFunc->etype)
1535 && !FUNC_ISNAKED(currFunc->type)) {
1537 // make sure all predecessors of the last block end in a return
1538 for (bp=setFirstItem(ebbi->bbOrder[ebbi->count-1]->predList);
1540 bp=setNextItem(ebbi->bbOrder[ebbi->count-1]->predList)) {
1541 if (bp->ech->op != RETURN) {
1542 werrorfl (bp->ech->filename, bp->ech->lineno,
1543 W_VOID_FUNC, currFunc->name);
1550 /* if cyclomatic info requested then print it */
1551 if (options.cyclomatic)
1552 printCyclomatic (ebbi->bbOrder, ebbi->count);
1554 /* convert operations with support routines
1555 written in C to function calls : I am doing
1556 this at this point since I want all the
1557 operations to be as they are for optimzations */
1558 convertToFcall (ebbi->bbOrder, ebbi->count);
1560 /* compute the live ranges */
1561 computeLiveRanges (ebbi->bbOrder, ebbi->count, TRUE);
1563 if (options.dump_range)
1564 dumpEbbsToFileExt (DUMP_RANGE, ebbi);
1566 /* Now that we have the live ranges, discard parameter
1567 * receives for unused parameters.
1569 discardDeadParamReceives (ebbi->bbOrder, ebbi->count);
1571 /* allocate registers & generate code */
1572 port->assignRegisters (ebbi);
1574 /* throw away blocks */
1575 setToNull ((void *) &graphEdges);
1581 /* (add-hook 'c-mode-hook (lambda () (setq c-basic-offset 4))) */