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 -------------------------------------------------------------------------*/
31 /*-----------------------------------------------------------------*/
32 /* global variables */
38 /*-----------------------------------------------------------------*/
39 /* printSymName - prints the symbol names */
40 /*-----------------------------------------------------------------*/
42 printSymName (void *vsym)
45 fprintf (stdout, " %s ", sym->name);
49 /*-----------------------------------------------------------------*/
50 /* cnvToFcall - does the actual conversion to function call */
51 /*-----------------------------------------------------------------*/
53 cnvToFcall (iCode * ic, eBBlock * ebp)
60 int lineno = ic->lineno;
63 ip = ic->next; /* insertion point */
64 /* remove it from the iCode */
65 remiCodeFromeBBlock (ebp, ic);
68 right = IC_RIGHT (ic);
70 if(IS_FLOAT(operandType( IC_RIGHT( ic ) ))) {
105 if(IS_FIXED16X16 (operandType (IC_RIGHT(ic)))) {
109 func = __fps16x16_add;
112 func = __fps16x16_sub;
115 func = __fps16x16_div;
118 func = __fps16x16_mul;
121 func = __fps16x16_eq;
124 func = __fps16x16_neq;
127 func = __fps16x16_lt;
130 func = __fps16x16_gt;
133 func = __fps16x16_lteq;
136 func = __fps16x16_gteq;
142 /* if float support routines NOT compiled as reentrant */
143 if (!options.float_rent)
147 if (IS_REGPARM (FUNC_ARGS(func->type)->etype))
149 newic = newiCode (SEND, IC_LEFT (ic), NULL);
150 newic->argreg = SPEC_ARGREG(FUNC_ARGS(func->type)->etype);
154 newic = newiCode ('=', NULL, IC_LEFT (ic));
155 IC_RESULT (newic) = operandFromValue (FUNC_ARGS(func->type));
158 addiCodeToeBBlock (ebp, newic, ip);
159 newic->lineno = lineno;
162 if (IS_REGPARM (FUNC_ARGS(func->type)->next->etype))
164 newic = newiCode (SEND, IC_RIGHT (ic), NULL);
165 newic->argreg = SPEC_ARGREG(FUNC_ARGS(func->type)->next->etype);
169 newic = newiCode ('=', NULL, IC_RIGHT (ic));
170 IC_RESULT (newic) = operandFromValue (FUNC_ARGS(func->type)->next);
172 addiCodeToeBBlock (ebp, newic, ip);
173 newic->lineno = lineno;
180 if (IS_REGPARM (FUNC_ARGS(func->type)->next->etype))
182 newic = newiCode (SEND, right, NULL);
183 newic->argreg = SPEC_ARGREG(FUNC_ARGS(func->type)->next->etype);
187 newic = newiCode (IPUSH, right, NULL);
190 bytesPushed += getSize(operandType(right));
193 addiCodeToeBBlock (ebp, newic, ip);
194 newic->lineno = lineno;
196 /* insert push left */
197 if (IS_REGPARM (FUNC_ARGS(func->type)->etype))
199 newic = newiCode (SEND, left, NULL);
200 newic->argreg = SPEC_ARGREG(FUNC_ARGS(func->type)->etype);
204 newic = newiCode (IPUSH, left, NULL);
207 bytesPushed += getSize(operandType(left));
209 addiCodeToeBBlock (ebp, newic, ip);
210 newic->lineno = lineno;
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;
219 FUNC_HASFCALL (currFunc->type) = 1;
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 */
225 if(!SPEC_EXTR(func->etype)) {
226 memmap *seg = SPEC_OCLS(OP_SYMBOL(IC_LEFT(newic))->etype);
228 SPEC_EXTR(func->etype) = 1;
229 seg = SPEC_OCLS( func->etype );
230 addSet(&seg->syms, func);
234 addiCodeToeBBlock (ebp, newic, ip);
237 /*-----------------------------------------------------------------*/
238 /* cnvToFloatCast - converts casts to floats to function calls */
239 /*-----------------------------------------------------------------*/
241 cnvToFloatCast (iCode * ic, eBBlock * ebp)
245 sym_link *type = operandType (IC_RIGHT (ic));
246 int linenno = ic->lineno;
251 /* remove it from the iCode */
252 remiCodeFromeBBlock (ebp, ic);
253 /* depending on the type */
254 for (bwd = 0; bwd < 3; bwd++)
256 for (su = 0; su < 2; su++)
258 if (compareType (type, __multypes[bwd][su]) == 1)
260 func = __conv[0][bwd][su];
266 if(compareType (type, fixed16x16Type) == 1) {
267 func = __fp16x16conv[0][3][0];
274 /* if float support routines NOT compiled as reentrant */
275 if (!options.float_rent)
278 if (IS_REGPARM (FUNC_ARGS(func->type)->etype))
280 newic = newiCode (SEND, IC_RIGHT (ic), NULL);
281 newic->argreg = SPEC_ARGREG(FUNC_ARGS(func->type)->etype);
285 newic = newiCode ('=', NULL, IC_RIGHT (ic));
286 IC_RESULT (newic) = operandFromValue (FUNC_ARGS(func->type));
288 addiCodeToeBBlock (ebp, newic, ip);
289 newic->lineno = linenno;
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);
301 newic = newiCode (IPUSH, IC_RIGHT (ic), NULL);
303 bytesPushed += getSize(operandType(IC_RIGHT(ic)));
305 addiCodeToeBBlock (ebp, newic, ip);
306 newic->lineno = linenno;
311 newic = newiCode (CALL, operandFromSymbol (func), NULL);
312 IC_RESULT (newic) = IC_RESULT (ic);
313 newic->parmBytes+=bytesPushed;
316 FUNC_HASFCALL (currFunc->type) = 1;
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 */
322 if(!SPEC_EXTR(func->etype)) {
323 memmap *seg = SPEC_OCLS(OP_SYMBOL(IC_LEFT(newic))->etype);
325 SPEC_EXTR(func->etype) = 1;
326 seg = SPEC_OCLS( func->etype );
327 addSet(&seg->syms, func);
331 addiCodeToeBBlock (ebp, newic, ip);
332 newic->lineno = linenno;
335 /*----------------------------------------------------------------------*/
336 /* cnvToFixed16x16Cast - converts casts to fixed16x16 to function calls */
337 /*----------------------------------------------------------------------*/
339 cnvToFixed16x16Cast (iCode * ic, eBBlock * ebp)
343 sym_link *type = operandType (IC_RIGHT (ic));
344 int linenno = ic->lineno;
349 /* remove it from the iCode */
350 remiCodeFromeBBlock (ebp, ic);
351 /* depending on the type */
352 for (bwd = 0; bwd < 3; bwd++)
354 for (su = 0; su < 2; su++)
356 if (compareType (type, __multypes[bwd][su]) == 1)
358 func = __fp16x16conv[0][bwd][su];
366 /* if float support routines NOT compiled as reentrant */
367 if (!options.float_rent)
370 if (IS_REGPARM (FUNC_ARGS(func->type)->etype))
372 newic = newiCode (SEND, IC_RIGHT (ic), NULL);
373 newic->argreg = SPEC_ARGREG(FUNC_ARGS(func->type)->etype);
377 newic = newiCode ('=', NULL, IC_RIGHT (ic));
378 IC_RESULT (newic) = operandFromValue (FUNC_ARGS(func->type));
380 addiCodeToeBBlock (ebp, newic, ip);
381 newic->lineno = linenno;
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);
393 newic = newiCode (IPUSH, IC_RIGHT (ic), NULL);
395 bytesPushed += getSize(operandType(IC_RIGHT(ic)));
397 addiCodeToeBBlock (ebp, newic, ip);
398 newic->lineno = linenno;
403 newic = newiCode (CALL, operandFromSymbol (func), NULL);
404 IC_RESULT (newic) = IC_RESULT (ic);
405 newic->parmBytes+=bytesPushed;
408 FUNC_HASFCALL (currFunc->type) = 1;
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 */
414 if(!SPEC_EXTR(func->etype)) {
415 memmap *seg = SPEC_OCLS(OP_SYMBOL(IC_LEFT(newic))->etype);
417 SPEC_EXTR(func->etype) = 1;
418 seg = SPEC_OCLS( func->etype );
419 addSet(&seg->syms, func);
423 addiCodeToeBBlock (ebp, newic, ip);
424 newic->lineno = linenno;
427 /*-----------------------------------------------------------------*/
428 /* cnvFromFloatCast - converts casts From floats to function calls */
429 /*-----------------------------------------------------------------*/
431 cnvFromFloatCast (iCode * ic, eBBlock * ebp)
435 sym_link *type = operandType (IC_LEFT (ic));
436 int lineno = ic->lineno;
441 /* remove it from the iCode */
442 remiCodeFromeBBlock (ebp, ic);
444 /* depending on the type */
445 for (bwd = 0; bwd < 3; bwd++)
447 for (su = 0; su < 2; su++)
449 if (compareType (type, __multypes[bwd][su]) == 1)
451 func = __conv[1][bwd][su];
459 /* if float support routines NOT compiled as reentrant */
460 if (!options.float_rent)
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);
469 newic = newiCode ('=', NULL, IC_RIGHT (ic));
470 IC_RESULT (newic) = operandFromValue (FUNC_ARGS(func->type));
472 addiCodeToeBBlock (ebp, newic, ip);
473 newic->lineno = lineno;
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);
486 newic = newiCode (IPUSH, IC_RIGHT (ic), NULL);
488 bytesPushed += getSize(operandType(IC_RIGHT(ic)));
490 addiCodeToeBBlock (ebp, newic, ip);
491 newic->lineno = lineno;
496 newic = newiCode (CALL, operandFromSymbol (func), NULL);
497 IC_RESULT (newic) = IC_RESULT (ic);
498 newic->parmBytes+=bytesPushed;
501 FUNC_HASFCALL (currFunc->type) = 1;
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 */
507 if(!SPEC_EXTR(func->etype)) {
508 memmap *seg = SPEC_OCLS(OP_SYMBOL(IC_LEFT(newic))->etype);
510 SPEC_EXTR(func->etype) = 1;
511 seg = SPEC_OCLS( func->etype );
512 addSet(&seg->syms, func);
516 addiCodeToeBBlock (ebp, newic, ip);
517 newic->lineno = lineno;
520 /*--------------------------------------------------------------------------*/
521 /* cnvFromFixed16x16Cast - converts casts from fixed16x16 to function calls */
522 /*--------------------------------------------------------------------------*/
524 cnvFromFixed16x16Cast (iCode * ic, eBBlock * ebp)
528 sym_link *type = operandType (IC_LEFT (ic));
529 int lineno = ic->lineno;
534 /* remove it from the iCode */
535 remiCodeFromeBBlock (ebp, ic);
537 /* depending on the type */
538 for (bwd = 0; bwd < 3; bwd++)
540 for (su = 0; su < 2; su++)
542 if (compareType (type, __multypes[bwd][su]) == 1)
544 func = __fp16x16conv[1][bwd][su];
550 if (compareType (type, floatType) == 1)
552 func = __fp16x16conv[1][3][0];
559 /* if float support routines NOT compiled as reentrant */
560 if (!options.float_rent)
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);
569 newic = newiCode ('=', NULL, IC_RIGHT (ic));
570 IC_RESULT (newic) = operandFromValue (FUNC_ARGS(func->type));
572 addiCodeToeBBlock (ebp, newic, ip);
573 newic->lineno = lineno;
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);
586 newic = newiCode (IPUSH, IC_RIGHT (ic), NULL);
588 bytesPushed += getSize(operandType(IC_RIGHT(ic)));
590 addiCodeToeBBlock (ebp, newic, ip);
591 newic->lineno = lineno;
596 newic = newiCode (CALL, operandFromSymbol (func), NULL);
597 IC_RESULT (newic) = IC_RESULT (ic);
598 newic->parmBytes+=bytesPushed;
601 FUNC_HASFCALL (currFunc->type) = 1;
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 */
607 if(!SPEC_EXTR(func->etype)) {
608 memmap *seg = SPEC_OCLS(OP_SYMBOL(IC_LEFT(newic))->etype);
610 SPEC_EXTR(func->etype) = 1;
611 seg = SPEC_OCLS( func->etype );
612 addSet(&seg->syms, func);
616 addiCodeToeBBlock (ebp, newic, ip);
617 newic->lineno = lineno;
620 extern operand *geniCodeRValue (operand *, bool);
622 /*-----------------------------------------------------------------*/
623 /* convilong - converts int or long mults or divs to fcalls */
624 /*-----------------------------------------------------------------*/
626 convilong (iCode * ic, eBBlock * ebp, sym_link * type, int op)
629 iCode *ip = ic->next;
631 int lineno = ic->lineno;
636 remiCodeFromeBBlock (ebp, ic);
638 /* depending on the type */
639 for (bwd = 0; bwd < 3; bwd++)
641 for (su = 0; su < 2; su++)
643 if (compareType (type, __multypes[bwd][su]) == 1)
646 func = __muldiv[0][bwd][su];
648 func = __muldiv[1][bwd][su];
650 func = __muldiv[2][bwd][su];
652 func = __rlrr[1][bwd][su];
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];
667 /* if int & long support routines NOT compiled as reentrant */
668 if (!options.intlong_rent)
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);
677 newic = newiCode ('=', NULL, IC_LEFT (ic));
678 IC_RESULT (newic) = operandFromValue (FUNC_ARGS(func->type));
680 addiCodeToeBBlock (ebp, newic, ip);
681 newic->lineno = lineno;
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);
690 newic = newiCode ('=', NULL, IC_RIGHT (ic));
691 IC_RESULT (newic) = operandFromValue (FUNC_ARGS(func->type)->next);
693 addiCodeToeBBlock (ebp, newic, ip);
694 newic->lineno = lineno;
699 /* compiled as reentrant then push */
701 if (IS_REGPARM (FUNC_ARGS(func->type)->next->etype))
703 newic = newiCode (SEND, IC_RIGHT (ic), NULL);
704 newic->argreg = SPEC_ARGREG(FUNC_ARGS(func->type)->next->etype);
708 newic = newiCode (IPUSH, IC_RIGHT (ic), NULL);
711 bytesPushed += getSize(operandType(IC_RIGHT(ic)));
713 addiCodeToeBBlock (ebp, newic, ip);
714 newic->lineno = lineno;
716 /* insert push left */
717 if (IS_REGPARM (FUNC_ARGS(func->type)->etype))
719 newic = newiCode (SEND, IC_LEFT (ic), NULL);
720 newic->argreg = SPEC_ARGREG(FUNC_ARGS(func->type)->etype);
724 newic = newiCode (IPUSH, IC_LEFT (ic), NULL);
727 bytesPushed += getSize(operandType(IC_LEFT(ic)));
729 addiCodeToeBBlock (ebp, newic, ip);
730 newic->lineno = lineno;
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
741 FUNC_HASFCALL (currFunc->type) = 1;
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 */
747 if(!SPEC_EXTR(func->etype)) {
748 memmap *seg = SPEC_OCLS(OP_SYMBOL(IC_LEFT(newic))->etype);
750 SPEC_EXTR(func->etype) = 1;
751 seg = SPEC_OCLS( func->etype );
752 addSet(&seg->syms, func);
756 addiCodeToeBBlock (ebp, newic, ip);
759 /*-----------------------------------------------------------------*/
760 /* convertToFcall - converts some operations to fcalls */
761 /*-----------------------------------------------------------------*/
763 convertToFcall (eBBlock ** ebbs, int count)
767 /* for all blocks do */
768 for (i = 0; i < count; i++)
772 /* for all instructions in the block do */
773 for (ic = ebbs[i]->sch; ic; ic = ic->next)
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)))))
784 cnvToFcall (ic, ebbs[i]);
787 /* casting is a little different */
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]);
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))))
805 unsigned litVal = abs((int)operandLitValue(IC_RIGHT(ic)));
807 // See if literal value is a power of 2.
808 while (litVal && !(litVal & 1))
814 // discard lowest set bit.
821 IC_RIGHT(ic) = operandFromLit(operandLitValue(IC_RIGHT(ic)) - 1);
826 /* if long / int mult or divide or mod */
827 if (ic->op == '*' || ic->op == '/' || ic->op == '%')
829 sym_link *leftType = operandType (IC_LEFT (ic));
831 if (IS_INTEGRAL (leftType) && getSize (leftType) > port->support.muldiv)
833 sym_link *rightType = operandType (IC_RIGHT (ic));
835 if (port->hasNativeMulFor != NULL &&
836 port->hasNativeMulFor (ic, leftType, rightType))
838 /* Leave as native */
842 convilong (ic, ebbs[i], leftType, ic->op);
847 if (ic->op == RRC || ic->op == RLC || ic->op == LEFT_OP || ic->op == RIGHT_OP)
849 sym_link *type = operandType (IC_LEFT (ic));
851 if (IS_INTEGRAL (type) && getSize (type) > port->support.shift && port->support.shift >= 0)
853 convilong (ic, ebbs[i], type, ic->op);
860 /*-----------------------------------------------------------------*/
861 /* isLocalWithoutDef - return 1 if sym might be used without a */
863 /*-----------------------------------------------------------------*/
865 isLocalWithoutDef (symbol * sym)
870 if (IS_VOLATILE (sym->type))
876 if (IS_AGGREGATE (sym->type))
885 /*-----------------------------------------------------------------*/
886 /* replaceRegEqv - replace all local variables with their reqv */
887 /*-----------------------------------------------------------------*/
889 replaceRegEqv (ebbIndex * ebbi)
891 eBBlock ** ebbs = ebbi->bbOrder;
892 int count = ebbi->count;
895 /* Update the symbols' def bitvector so we know if there is */
896 /* a defining iCode or not. Only replace a local variable */
897 /* with its register equivalent if there is a defining iCode; */
898 /* otherwise, the port's register allocater may choke. */
899 cseAllBlocks (ebbi, TRUE);
901 for (i = 0; i < count; i++)
906 for (ic = ebbs[i]->sch; ic; ic = ic->next)
915 IS_TRUE_SYMOP (IC_COND (ic)) &&
916 isLocalWithoutDef (OP_SYMBOL (IC_COND (ic))))
918 werrorfl (ic->filename, ic->lineno,
920 OP_SYMBOL (IC_COND (ic))->name);
921 OP_REQV (IC_COND (ic)) = NULL;
922 OP_SYMBOL (IC_COND (ic))->allocreq = 1;
925 if (IS_TRUE_SYMOP (IC_COND (ic)) &&
926 OP_REQV (IC_COND (ic)))
927 IC_COND (ic) = opFromOpWithDU (OP_REQV (IC_COND (ic)),
928 OP_SYMBOL (IC_COND (ic))->defs,
929 OP_SYMBOL (IC_COND (ic))->uses);
935 if (ic->op == JUMPTABLE)
937 if (IC_JTCOND (ic) &&
938 IS_TRUE_SYMOP (IC_JTCOND (ic)) &&
939 isLocalWithoutDef (OP_SYMBOL (IC_JTCOND (ic))))
941 werrorfl (ic->filename, ic->lineno,
943 OP_SYMBOL (IC_JTCOND (ic))->name);
944 OP_REQV (IC_JTCOND (ic)) = NULL;
945 OP_SYMBOL (IC_JTCOND (ic))->allocreq = 1;
948 if (IS_TRUE_SYMOP (IC_JTCOND (ic)) &&
949 OP_REQV (IC_JTCOND (ic)))
950 IC_JTCOND (ic) = opFromOpWithDU (OP_REQV (IC_JTCOND (ic)),
951 OP_SYMBOL (IC_JTCOND (ic))->defs,
952 OP_SYMBOL (IC_JTCOND (ic))->uses);
956 if (ic->op == RECEIVE)
958 if (OP_SYMBOL (IC_RESULT (ic))->addrtaken)
959 OP_SYMBOL (IC_RESULT (ic))->isspilt = 1;
963 if (IC_RESULT (ic) &&
964 IS_TRUE_SYMOP (IC_RESULT (ic)) &&
965 OP_REQV (IC_RESULT (ic)))
967 if (POINTER_SET (ic))
969 IC_RESULT (ic) = opFromOpWithDU (OP_REQV (IC_RESULT (ic)),
970 OP_SYMBOL (IC_RESULT (ic))->defs,
971 OP_SYMBOL (IC_RESULT (ic))->uses);
972 IC_RESULT (ic)->isaddr = 1;
975 IC_RESULT (ic) = opFromOpWithDU (OP_REQV (IC_RESULT (ic)),
976 OP_SYMBOL (IC_RESULT (ic))->defs,
977 OP_SYMBOL (IC_RESULT (ic))->uses);
981 IS_TRUE_SYMOP (IC_RIGHT (ic)) &&
982 isLocalWithoutDef (OP_SYMBOL (IC_RIGHT (ic))))
984 werrorfl (ic->filename, ic->lineno,
986 OP_SYMBOL (IC_RIGHT (ic))->name);
987 OP_REQV (IC_RIGHT (ic)) = NULL;
988 OP_SYMBOL (IC_RIGHT (ic))->allocreq = 1;
992 IS_TRUE_SYMOP (IC_RIGHT (ic)) &&
993 OP_REQV (IC_RIGHT (ic)))
995 IC_RIGHT (ic) = opFromOpWithDU (OP_REQV (IC_RIGHT (ic)),
996 OP_SYMBOL (IC_RIGHT (ic))->defs,
997 OP_SYMBOL (IC_RIGHT (ic))->uses);
998 IC_RIGHT (ic)->isaddr = 0;
1002 IS_TRUE_SYMOP (IC_LEFT (ic)) &&
1003 isLocalWithoutDef (OP_SYMBOL (IC_LEFT (ic))))
1005 werrorfl (ic->filename, ic->lineno,
1007 OP_SYMBOL (IC_LEFT (ic))->name);
1008 OP_REQV (IC_LEFT (ic)) = NULL;
1009 OP_SYMBOL (IC_LEFT (ic))->allocreq = 1;
1013 IS_TRUE_SYMOP (IC_LEFT (ic)) &&
1014 OP_REQV (IC_LEFT (ic)))
1016 IC_LEFT (ic) = opFromOpWithDU (OP_REQV (IC_LEFT (ic)),
1017 OP_SYMBOL (IC_LEFT (ic))->defs,
1018 OP_SYMBOL (IC_LEFT (ic))->uses);
1019 IC_LEFT (ic)->isaddr = 0;
1025 /*-----------------------------------------------------------------*/
1026 /* findReqv - search for a register equivalent */
1027 /*-----------------------------------------------------------------*/
1029 findReqv (symbol * prereqv, eBBlock ** ebbs, int count)
1034 /* for all blocks do */
1035 for (i=0; i<count; i++)
1037 /* for all instructions in the block do */
1038 for (ic = ebbs[i]->sch; ic; ic = ic->next)
1042 if (IS_ITEMP (IC_COND (ic))
1043 && OP_SYMBOL (IC_COND (ic))->prereqv == prereqv)
1044 return IC_COND (ic);
1046 else if (ic->op == JUMPTABLE)
1048 if (IS_ITEMP (IC_JTCOND (ic))
1049 && OP_SYMBOL (IC_JTCOND (ic))->prereqv == prereqv)
1050 return IC_JTCOND (ic);
1054 if (IS_ITEMP (IC_LEFT (ic))
1055 && OP_SYMBOL (IC_LEFT (ic))->prereqv == prereqv)
1056 return IC_LEFT (ic);
1057 if (IS_ITEMP (IC_RIGHT (ic))
1058 && OP_SYMBOL (IC_RIGHT (ic))->prereqv == prereqv)
1059 return IC_RIGHT (ic);
1060 if (IS_ITEMP (IC_RESULT (ic))
1061 && OP_SYMBOL (IC_RESULT (ic))->prereqv == prereqv)
1062 return IC_RESULT (ic);
1070 /*-----------------------------------------------------------------*/
1071 /* killDeadCode - eliminates dead assignments */
1072 /*-----------------------------------------------------------------*/
1074 killDeadCode (ebbIndex * ebbi)
1076 eBBlock ** ebbs = ebbi->dfOrder;
1077 int count = ebbi->count;
1083 /* basic algorithm :- */
1084 /* first the exclusion rules :- */
1085 /* 1. if result is a global or volatile then skip */
1086 /* 2. if assignment and result is a temp & isaddr then skip */
1087 /* since this means array & pointer access, will be taken */
1088 /* care of by alias analysis. */
1089 /* 3. if the result is used in the remainder of the block skip */
1090 /* 4. if this definition does not reach the end of the block */
1091 /* i.e. the result is not present in the outExprs then KILL */
1092 /* 5. if it reaches the end of block & is used by some success */
1095 /* this whole process is carried on iteratively till no change */
1100 /* for all blocks do */
1101 for (i = 0; i < count; i++)
1105 /* for all instructions in the block do */
1106 for (ic = ebbs[i]->sch; ic; ic = ic->next)
1114 ic->op == DUMMY_READ_VOLATILE ||
1115 ic->op == CRITICAL ||
1116 ic->op == ENDCRITICAL)
1119 /* Since both IFX & JUMPTABLE (in SKIP_IC) have been tested for */
1120 /* it is now safe to assume IC_LEFT, IC_RIGHT, & IC_RESULT are */
1123 /* if the result is volatile then continue */
1124 if (IC_RESULT (ic) && isOperandVolatile (IC_RESULT (ic), FALSE))
1127 /* if the result is a temp & isaddr then skip */
1128 if (IC_RESULT (ic) && POINTER_SET (ic))
1131 if (POINTER_GET (ic) && IS_VOLATILE (operandType (IC_LEFT (ic))->next)
1132 && !SPIL_LOC (IC_RESULT (ic)))
1135 /* if the result is used in the remainder of the */
1136 /* block then skip */
1137 if (usedInRemaining (IC_RESULT (ic), ic->next))
1140 /* does this definition reach the end of the block
1141 or the usage is zero then we can kill */
1142 if (!bitVectBitValue (ebbs[i]->outDefs, ic->key))
1143 kill = 1; /* if not we can kill it */
1146 /* if this is a global variable or function parameter */
1147 /* we cannot kill anyway */
1148 if (isOperandGlobal (IC_RESULT (ic)) ||
1149 (OP_SYMBOL (IC_RESULT (ic))->_isparm &&
1150 !OP_SYMBOL (IC_RESULT (ic))->ismyparm))
1153 /* if we are sure there are no usages */
1154 if (bitVectIsZero (OP_USES (IC_RESULT (ic))))
1160 /* reset visited flag */
1161 for (j = 0; j < count; ebbs[j++]->visited = 0);
1163 /* find out if this definition is alive */
1164 if (applyToSet (ebbs[i]->succList,
1173 /* kill this one if required */
1176 bool volLeft = IS_SYMOP (IC_LEFT (ic))
1177 && isOperandVolatile (IC_LEFT (ic), FALSE);
1178 bool volRight = IS_SYMOP (IC_RIGHT (ic))
1179 && isOperandVolatile (IC_RIGHT (ic), FALSE);
1181 /* a dead address-of operation should die, even if volatile */
1182 if (ic->op == ADDRESS_OF)
1185 if (ic->next && ic->seqPoint == ic->next->seqPoint
1186 && (ic->next->op == '+' || ic->next->op == '-'))
1188 if (isOperandEqual (IC_LEFT(ic), IC_LEFT(ic->next))
1189 || isOperandEqual (IC_LEFT(ic), IC_RIGHT(ic->next)))
1191 if (isOperandEqual (IC_RIGHT(ic), IC_LEFT(ic->next))
1192 || isOperandEqual (IC_RIGHT(ic), IC_RIGHT(ic->next)))
1196 if (POINTER_GET (ic) && IS_VOLATILE (operandType (IC_LEFT (ic))->next))
1198 if (SPIL_LOC (IC_RESULT (ic)))
1200 IC_RESULT (ic) = newiTempFromOp (IC_RESULT (ic));
1201 SPIL_LOC (IC_RESULT (ic)) = NULL;
1209 /* now delete from defUseSet */
1210 deleteItemIf (&ebbs[i]->outExprs, ifDiCodeIsX, ic);
1211 bitVectUnSetBit (ebbs[i]->outDefs, ic->key);
1213 /* and defset of the block */
1214 bitVectUnSetBit (ebbs[i]->defSet, ic->key);
1216 /* If this is the last of a register equivalent, */
1217 /* look for a successor register equivalent. */
1218 bitVectUnSetBit (OP_DEFS (IC_RESULT (ic)), ic->key);
1219 if (IS_ITEMP (IC_RESULT (ic))
1220 && OP_SYMBOL (IC_RESULT (ic))->isreqv
1221 && bitVectIsZero (OP_DEFS (IC_RESULT (ic))))
1223 symbol * resultsym = OP_SYMBOL (IC_RESULT (ic));
1224 symbol * prereqv = resultsym->prereqv;
1226 if (prereqv && prereqv->reqv && (OP_SYMBOL (prereqv->reqv) == resultsym))
1230 IC_RESULT (ic) = NULL;
1231 newreqv = findReqv (prereqv, ebbs, count);
1234 prereqv->reqv = newreqv;
1239 /* delete the result */
1240 IC_RESULT (ic) = NULL;
1242 if (volLeft || volRight)
1244 /* something is volatile, so keep the iCode */
1245 /* and change the operator instead */
1246 ic->op = DUMMY_READ_VOLATILE;
1248 /* keep only the volatile operands */
1250 IC_LEFT (ic) = NULL;
1252 IC_RIGHT (ic) = NULL;
1256 /* nothing is volatile, eliminate the iCode */
1257 remiCodeFromeBBlock (ebbs[i], ic);
1259 /* for the left & right remove the usage */
1260 if (IS_SYMOP (IC_LEFT (ic)))
1261 bitVectUnSetBit (OP_USES (IC_LEFT (ic)), ic->key);
1263 if (IS_SYMOP (IC_RIGHT (ic)))
1264 bitVectUnSetBit (OP_USES (IC_RIGHT (ic)), ic->key);
1268 } /* end of all instructions */
1270 if (!ebbs[i]->sch && !ebbs[i]->noPath)
1271 disconBBlock (ebbs[i], ebbi);
1273 } /* end of for all blocks */
1277 } /* end of while(1) */
1282 /*-----------------------------------------------------------------*/
1283 /* printCyclomatic - prints the cyclomatic information */
1284 /*-----------------------------------------------------------------*/
1286 printCyclomatic (eBBlock ** ebbs, int count)
1288 int nEdges = elementsInSet (graphEdges);
1291 for (i = 0; i < count; i++)
1292 nNodes += (!ebbs[i]->noPath);
1294 /* print the information */
1295 werror (I_CYCLOMATIC, currFunc->name, nEdges, nNodes, nEdges - nNodes + 2);
1298 /*-----------------------------------------------------------------*/
1299 /* discardDeadParamReceives - remove any RECEIVE opcodes which */
1300 /* refer to dead variables. */
1301 /*-----------------------------------------------------------------*/
1303 discardDeadParamReceives (eBBlock ** ebbs, int count)
1309 for (i = 0; i < count; i++)
1311 for (ic = ebbs[i]->sch; ic; ic = ic->next)
1313 if (ic->op == RECEIVE)
1315 if (IC_RESULT (ic) && OP_SYMBOL (IC_RESULT (ic))
1316 && !OP_SYMBOL (IC_RESULT (ic))->used)
1319 fprintf (stderr, "discarding dead receive for %s\n",
1320 OP_SYMBOL (IC_RESULT (ic))->name);
1322 dummyIcode.next = ic->next;
1323 remiCodeFromeBBlock (ebbs[i], ic);
1331 /*-----------------------------------------------------------------*/
1332 /* optimizeCastCast - remove unneeded intermediate casts. */
1333 /* Integer promotion may cast (un)signed char to int and then */
1334 /* recast the int to (un)signed long. If the signedness of the */
1335 /* char and long are the same, the cast can be safely performed in */
1336 /* a single step. */
1337 /*-----------------------------------------------------------------*/
1339 optimizeCastCast (eBBlock ** ebbs, int count)
1349 for (i = 0; i < count; i++)
1351 for (ic = ebbs[i]->sch; ic; ic = ic->next)
1354 if (ic->op == CAST && IC_RESULT (ic) && IS_ITEMP (IC_RESULT (ic)))
1356 type1 = operandType (IC_RIGHT (ic));
1357 type2 = operandType (IC_RESULT (ic));
1359 /* Look only for a cast from an integer type to an */
1360 /* integer type that has no loss of bits */
1361 if (!IS_INTEGRAL (type1) || !IS_INTEGRAL (type2))
1363 if (getSize (type2) < getSize (type1))
1366 /* There must be only one use of this first result */
1367 if (bitVectnBitsOn (OP_USES (IC_RESULT (ic))) != 1)
1370 /* This use must be a second cast */
1371 uic = hTabItemWithKey (iCodehTab,
1372 bitVectFirstBit (OP_USES (IC_RESULT (ic))));
1373 if (!uic || uic->op != CAST)
1376 /* It must be a cast to another integer type that */
1377 /* has no loss of bits */
1378 type3 = operandType (IC_RESULT (uic));
1379 if (!IS_INTEGRAL (type3))
1381 if (getSize (type3) < getSize (type2))
1384 /* The signedness between the first and last types */
1386 if (SPEC_USIGN (type3) != SPEC_USIGN (type1))
1389 /* Change the first cast to a simple assignment and */
1390 /* let the second cast do all the work */
1392 IC_LEFT (ic) = NULL;
1393 sym = OP_SYMBOL (IC_RESULT (ic));
1394 sym->type = copyLinkChain (type1);
1395 sym->etype = getSpec (sym->type);
1401 /*-----------------------------------------------------------------*/
1402 /* eBBlockFromiCode - creates extended basic blocks from iCode */
1403 /* will return an array of eBBlock pointers */
1404 /*-----------------------------------------------------------------*/
1406 eBBlockFromiCode (iCode * ic)
1408 ebbIndex *ebbi = NULL;
1414 /* if nothing passed then return nothing */
1420 /* optimize the chain for labels & gotos
1421 this will eliminate redundant labels and
1422 will change jump to jumps by jumps */
1423 ic = iCodeLabelOptimize (ic);
1425 /* break it down into basic blocks */
1426 ebbi = iCodeBreakDown (ic);
1428 /* hash the iCode keys so that we can quickly index */
1429 /* them in the rest of the optimization steps */
1430 setToNull ((void *) &iCodehTab);
1431 iCodehTab = newHashTable (iCodeKey);
1432 hashiCodeKeys (ebbi->bbOrder, ebbi->count);
1434 /* compute the control flow */
1435 computeControlFlow (ebbi);
1437 /* dumpraw if asked for */
1438 if (options.dump_raw)
1439 dumpEbbsToFileExt (DUMP_RAW0, ebbi);
1441 /* replace the local variables with their
1442 register equivalents : the liveRange computation
1443 along with the register allocation will determine
1444 if it finally stays in the registers */
1445 replaceRegEqv (ebbi);
1447 /* create loop regions */
1448 loops = createLoopRegions (ebbi);
1450 /* dumpraw if asked for */
1451 if (options.dump_raw)
1452 dumpEbbsToFileExt (DUMP_RAW1, ebbi);
1454 optimizeCastCast (ebbi->bbOrder, ebbi->count);
1456 /* do common subexpression elimination for each block */
1457 change = cseAllBlocks (ebbi, FALSE);
1459 /* dumpraw if asked for */
1460 if (options.dump_raw)
1461 dumpEbbsToFileExt (DUMP_CSE, ebbi);
1463 /* compute the data flow */
1464 computeDataFlow (ebbi);
1466 /* dumpraw if asked for */
1467 if (options.dump_raw)
1468 dumpEbbsToFileExt (DUMP_DFLOW, ebbi);
1470 /* global common subexpression elimination */
1471 if (optimize.global_cse)
1473 change += cseAllBlocks (ebbi, FALSE);
1474 if (options.dump_gcse)
1475 dumpEbbsToFileExt (DUMP_GCSE, ebbi);
1479 // compute the dataflow only
1480 assert(cseAllBlocks (ebbi, TRUE)==0);
1482 /* kill dead code */
1483 kchange = killDeadCode (ebbi);
1485 if (options.dump_kill)
1486 dumpEbbsToFileExt (DUMP_DEADCODE, ebbi);
1488 /* do loop optimizations */
1489 change += (lchange = loopOptimizations (loops, ebbi));
1490 if (options.dump_loop)
1491 dumpEbbsToFileExt (DUMP_LOOP, ebbi);
1493 /* recompute the data flow and apply global cse again
1494 if loops optimizations or dead code caused a change:
1495 loops will brings out of the loop which then may be
1496 available for use in the later blocks: dead code
1497 elimination could potentially disconnect some blocks
1498 conditional flow may be efected so we need to apply
1499 subexpression once more */
1500 if (lchange || kchange)
1502 computeDataFlow (ebbi);
1503 change += cseAllBlocks (ebbi, FALSE);
1504 if (options.dump_loop)
1505 dumpEbbsToFileExt (DUMP_LOOPG, ebbi);
1507 /* if loop optimizations caused a change then do
1508 dead code elimination once more : this will
1509 get rid of the extra assignments to the induction
1510 variables created during loop optimizations */
1511 killDeadCode (ebbi);
1513 if (options.dump_loop)
1514 dumpEbbsToFileExt (DUMP_LOOPD, ebbi);
1518 /* sort it back by block number */
1519 //qsort (ebbs, saveCount, sizeof (eBBlock *), bbNumCompare);
1521 if (!options.lessPedantic) {
1522 // this is a good place to check missing return values
1524 // the user is on his own with naked functions...
1525 if (!IS_VOID(currFunc->etype)
1526 && !FUNC_ISNAKED(currFunc->type)) {
1528 // make sure all predecessors of the last block end in a return
1529 for (bp=setFirstItem(ebbi->bbOrder[ebbi->count-1]->predList);
1531 bp=setNextItem(ebbi->bbOrder[ebbi->count-1]->predList)) {
1532 if (bp->ech->op != RETURN) {
1533 werrorfl (bp->ech->filename, bp->ech->lineno,
1534 W_VOID_FUNC, currFunc->name);
1541 /* if cyclomatic info requested then print it */
1542 if (options.cyclomatic)
1543 printCyclomatic (ebbi->bbOrder, ebbi->count);
1545 /* convert operations with support routines
1546 written in C to function calls : Iam doing
1547 this at this point since I want all the
1548 operations to be as they are for optimzations */
1549 convertToFcall (ebbi->bbOrder, ebbi->count);
1551 /* compute the live ranges */
1552 computeLiveRanges (ebbi->bbOrder, ebbi->count);
1554 if (options.dump_range)
1555 dumpEbbsToFileExt (DUMP_RANGE, ebbi);
1557 /* Now that we have the live ranges, discard parameter
1558 * receives for unused parameters.
1560 discardDeadParamReceives (ebbi->bbOrder, ebbi->count);
1562 /* allocate registers & generate code */
1563 port->assignRegisters (ebbi);
1565 /* throw away blocks */
1566 setToNull ((void *) &graphEdges);
1572 /* (add-hook 'c-mode-hook (lambda () (setq c-basic-offset 4))) */