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);
104 /* if float support routines NOT compiled as reentrant */
105 if (!options.float_rent)
109 if (IS_REGPARM (FUNC_ARGS(func->type)->etype))
111 newic = newiCode (SEND, IC_LEFT (ic), NULL);
112 newic->argreg = SPEC_ARGREG(FUNC_ARGS(func->type)->etype);
116 newic = newiCode ('=', NULL, IC_LEFT (ic));
117 IC_RESULT (newic) = operandFromValue (FUNC_ARGS(func->type));
120 addiCodeToeBBlock (ebp, newic, ip);
121 newic->lineno = lineno;
124 if (IS_REGPARM (FUNC_ARGS(func->type)->next->etype))
126 newic = newiCode (SEND, IC_RIGHT (ic), NULL);
127 newic->argreg = SPEC_ARGREG(FUNC_ARGS(func->type)->next->etype);
131 newic = newiCode ('=', NULL, IC_RIGHT (ic));
132 IC_RESULT (newic) = operandFromValue (FUNC_ARGS(func->type)->next);
134 addiCodeToeBBlock (ebp, newic, ip);
135 newic->lineno = lineno;
142 if (IS_REGPARM (FUNC_ARGS(func->type)->next->etype))
144 newic = newiCode (SEND, right, NULL);
145 newic->argreg = SPEC_ARGREG(FUNC_ARGS(func->type)->next->etype);
149 newic = newiCode (IPUSH, right, NULL);
152 bytesPushed += getSize(operandType(right));
155 addiCodeToeBBlock (ebp, newic, ip);
156 newic->lineno = lineno;
158 /* insert push left */
159 if (IS_REGPARM (FUNC_ARGS(func->type)->etype))
161 newic = newiCode (SEND, left, NULL);
162 newic->argreg = SPEC_ARGREG(FUNC_ARGS(func->type)->etype);
166 newic = newiCode (IPUSH, left, NULL);
169 bytesPushed += getSize(operandType(left));
171 addiCodeToeBBlock (ebp, newic, ip);
172 newic->lineno = lineno;
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;
180 if(TARGET_IS_PIC16) {
181 /* normally these functions aren't marked external, so we can use their
182 * _extern field to marked as already added to symbol table */
184 if(!SPEC_EXTR(func->etype)) {
185 memmap *seg = SPEC_OCLS(OP_SYMBOL(IC_LEFT(newic))->etype);
187 SPEC_EXTR(func->etype) = 1;
188 seg = SPEC_OCLS( func->etype );
189 addSet(&seg->syms, func);
193 addiCodeToeBBlock (ebp, newic, ip);
196 /*-----------------------------------------------------------------*/
197 /* cnvToFloatCast - converts casts to floats to function calls */
198 /*-----------------------------------------------------------------*/
200 cnvToFloatCast (iCode * ic, eBBlock * ebp)
204 sym_link *type = operandType (IC_RIGHT (ic));
205 int linenno = ic->lineno;
210 /* remove it from the iCode */
211 remiCodeFromeBBlock (ebp, ic);
212 /* depending on the type */
213 for (bwd = 0; bwd < 3; bwd++)
215 for (su = 0; su < 2; su++)
217 if (compareType (type, __multypes[bwd][su]) == 1)
219 func = __conv[0][bwd][su];
227 /* if float support routines NOT compiled as reentrant */
228 if (!options.float_rent)
231 if (IS_REGPARM (FUNC_ARGS(func->type)->etype))
233 newic = newiCode (SEND, IC_RIGHT (ic), NULL);
234 newic->argreg = SPEC_ARGREG(FUNC_ARGS(func->type)->etype);
238 newic = newiCode ('=', NULL, IC_RIGHT (ic));
239 IC_RESULT (newic) = operandFromValue (FUNC_ARGS(func->type));
241 addiCodeToeBBlock (ebp, newic, ip);
242 newic->lineno = linenno;
248 if (IS_REGPARM (FUNC_ARGS(func->type)->etype)) {
249 newic = newiCode (SEND, IC_RIGHT (ic), NULL);
250 newic->argreg = SPEC_ARGREG(FUNC_ARGS(func->type)->etype);
254 newic = newiCode (IPUSH, IC_RIGHT (ic), NULL);
256 bytesPushed += getSize(operandType(IC_RIGHT(ic)));
258 addiCodeToeBBlock (ebp, newic, ip);
259 newic->lineno = linenno;
264 newic = newiCode (CALL, operandFromSymbol (func), NULL);
265 IC_RESULT (newic) = IC_RESULT (ic);
266 newic->parmBytes+=bytesPushed;
268 if(TARGET_IS_PIC16) {
269 /* normally these functions aren't marked external, so we can use their
270 * _extern field to marked as already added to symbol table */
272 if(!SPEC_EXTR(func->etype)) {
273 memmap *seg = SPEC_OCLS(OP_SYMBOL(IC_LEFT(newic))->etype);
275 SPEC_EXTR(func->etype) = 1;
276 seg = SPEC_OCLS( func->etype );
277 addSet(&seg->syms, func);
281 addiCodeToeBBlock (ebp, newic, ip);
282 newic->lineno = linenno;
285 /*-----------------------------------------------------------------*/
286 /* cnvFromFloatCast - converts casts From floats to function calls */
287 /*-----------------------------------------------------------------*/
289 cnvFromFloatCast (iCode * ic, eBBlock * ebp)
293 sym_link *type = operandType (IC_LEFT (ic));
294 int lineno = ic->lineno;
299 /* remove it from the iCode */
300 remiCodeFromeBBlock (ebp, ic);
302 /* depending on the type */
303 for (bwd = 0; bwd < 3; bwd++)
305 for (su = 0; su < 2; su++)
307 if (compareType (type, __multypes[bwd][su]) == 1)
309 func = __conv[1][bwd][su];
317 /* if float support routines NOT compiled as reentrant */
318 if (!options.float_rent)
321 if (IS_REGPARM (FUNC_ARGS(func->type)->etype)) {
322 newic = newiCode (SEND, IC_RIGHT (ic), NULL);
323 newic->argreg = SPEC_ARGREG(FUNC_ARGS(func->type)->etype);
327 newic = newiCode ('=', NULL, IC_RIGHT (ic));
328 IC_RESULT (newic) = operandFromValue (FUNC_ARGS(func->type));
330 addiCodeToeBBlock (ebp, newic, ip);
331 newic->lineno = lineno;
338 if (IS_REGPARM (FUNC_ARGS(func->type)->etype)) {
339 newic = newiCode (SEND, IC_RIGHT (ic), NULL);
340 newic->argreg = SPEC_ARGREG(FUNC_ARGS(func->type)->etype);
344 newic = newiCode (IPUSH, IC_RIGHT (ic), NULL);
346 bytesPushed += getSize(operandType(IC_RIGHT(ic)));
348 addiCodeToeBBlock (ebp, newic, ip);
349 newic->lineno = lineno;
354 newic = newiCode (CALL, operandFromSymbol (func), NULL);
355 IC_RESULT (newic) = IC_RESULT (ic);
356 newic->parmBytes+=bytesPushed;
358 if(TARGET_IS_PIC16) {
359 /* normally these functions aren't marked external, so we can use their
360 * _extern field to marked as already added to symbol table */
362 if(!SPEC_EXTR(func->etype)) {
363 memmap *seg = SPEC_OCLS(OP_SYMBOL(IC_LEFT(newic))->etype);
365 SPEC_EXTR(func->etype) = 1;
366 seg = SPEC_OCLS( func->etype );
367 addSet(&seg->syms, func);
371 addiCodeToeBBlock (ebp, newic, ip);
372 newic->lineno = lineno;
375 extern operand *geniCodeRValue (operand *, bool);
377 /*-----------------------------------------------------------------*/
378 /* convilong - converts int or long mults or divs to fcalls */
379 /*-----------------------------------------------------------------*/
381 convilong (iCode * ic, eBBlock * ebp, sym_link * type, int op)
384 iCode *ip = ic->next;
386 int lineno = ic->lineno;
391 // Easy special case which avoids function call: modulo by a literal power
392 // of two can be replaced by a bitwise AND.
393 if (op == '%' && isOperandLiteral(IC_RIGHT(ic)))
395 unsigned litVal = (unsigned)(operandLitValue(IC_RIGHT(ic)));
397 // See if literal value is a power of 2.
398 while (litVal && !(litVal & 1))
404 // discard first high bit set.
411 IC_RIGHT(ic) = operandFromLit(operandLitValue(IC_RIGHT(ic)) - 1);
416 remiCodeFromeBBlock (ebp, ic);
419 /* depending on the type */
420 for (bwd = 0; bwd < 3; bwd++)
422 for (su = 0; su < 2; su++)
424 if (compareType (type, __multypes[bwd][su]) == 1)
427 func = __muldiv[0][bwd][su];
429 func = __muldiv[1][bwd][su];
431 func = __muldiv[2][bwd][su];
433 func = __rlrr[1][bwd][su];
435 func = __rlrr[0][bwd][su];
436 else if (op == RIGHT_OP)
437 func = __rlrr[1][bwd][su];
438 else if (op == LEFT_OP)
439 func = __rlrr[0][bwd][su];
448 /* if int & long support routines NOT compiled as reentrant */
449 if (!options.intlong_rent)
452 if (IS_REGPARM (FUNC_ARGS(func->type)->etype)) {
453 newic = newiCode (SEND, IC_LEFT (ic), NULL);
454 newic->argreg = SPEC_ARGREG(FUNC_ARGS(func->type)->etype);
458 newic = newiCode ('=', NULL, IC_LEFT (ic));
459 IC_RESULT (newic) = operandFromValue (FUNC_ARGS(func->type));
461 addiCodeToeBBlock (ebp, newic, ip);
462 newic->lineno = lineno;
465 if (IS_REGPARM (FUNC_ARGS(func->type)->next->etype)) {
466 newic = newiCode (SEND, IC_RIGHT (ic), NULL);
467 newic->argreg = SPEC_ARGREG(FUNC_ARGS(func->type)->next->etype);
471 newic = newiCode ('=', NULL, IC_RIGHT (ic));
472 IC_RESULT (newic) = operandFromValue (FUNC_ARGS(func->type)->next);
474 addiCodeToeBBlock (ebp, newic, ip);
475 newic->lineno = lineno;
480 /* compiled as reentrant then push */
482 if (IS_REGPARM (FUNC_ARGS(func->type)->next->etype))
484 newic = newiCode (SEND, IC_RIGHT (ic), NULL);
485 newic->argreg = SPEC_ARGREG(FUNC_ARGS(func->type)->next->etype);
489 newic = newiCode (IPUSH, IC_RIGHT (ic), NULL);
492 bytesPushed += getSize(operandType(IC_RIGHT(ic)));
494 addiCodeToeBBlock (ebp, newic, ip);
495 newic->lineno = lineno;
497 /* insert push left */
498 if (IS_REGPARM (FUNC_ARGS(func->type)->etype))
500 newic = newiCode (SEND, IC_LEFT (ic), NULL);
501 newic->argreg = SPEC_ARGREG(FUNC_ARGS(func->type)->etype);
505 newic = newiCode (IPUSH, IC_LEFT (ic), NULL);
508 bytesPushed += getSize(operandType(IC_LEFT(ic)));
510 addiCodeToeBBlock (ebp, newic, ip);
511 newic->lineno = lineno;
516 newic = newiCode (CALL, operandFromSymbol (func), NULL);
517 IC_RESULT (newic) = IC_RESULT (ic);
518 newic->lineno = lineno;
519 newic->parmBytes+=bytesPushed; // to clear the stack after the call
521 if(TARGET_IS_PIC16) {
522 /* normally these functions aren't marked external, so we can use their
523 * _extern field to marked as already added to symbol table */
525 if(!SPEC_EXTR(func->etype)) {
526 memmap *seg = SPEC_OCLS(OP_SYMBOL(IC_LEFT(newic))->etype);
528 SPEC_EXTR(func->etype) = 1;
529 seg = SPEC_OCLS( func->etype );
530 addSet(&seg->syms, func);
534 addiCodeToeBBlock (ebp, newic, ip);
537 /*-----------------------------------------------------------------*/
538 /* convertToFcall - converts some operations to fcalls */
539 /*-----------------------------------------------------------------*/
541 convertToFcall (eBBlock ** ebbs, int count)
545 /* for all blocks do */
546 for (i = 0; i < count; i++)
550 /* for all instructions in the block do */
551 for (ic = ebbs[i]->sch; ic; ic = ic->next)
554 /* floating point operations are
555 converted to function calls */
556 if ((IS_CONDITIONAL (ic) ||
557 IS_ARITHMETIC_OP (ic)) &&
558 (IS_FLOAT (operandType (IC_RIGHT (ic)))))
561 cnvToFcall (ic, ebbs[i]);
564 /* casting is a little different */
567 if (IS_FLOAT (operandType (IC_RIGHT (ic))))
568 cnvFromFloatCast (ic, ebbs[i]);
569 else if (IS_FLOAT (operandType (IC_LEFT (ic))))
570 cnvToFloatCast (ic, ebbs[i]);
573 /* if long / int mult or divide or mod */
574 if (ic->op == '*' || ic->op == '/' || ic->op == '%')
576 sym_link *leftType = operandType (IC_LEFT (ic));
578 if (IS_INTEGRAL (leftType) && getSize (leftType) > port->support.muldiv)
580 sym_link *rightType = operandType (IC_RIGHT (ic));
582 if (port->hasNativeMulFor != NULL &&
583 port->hasNativeMulFor (ic, leftType, rightType))
585 /* Leave as native */
589 convilong (ic, ebbs[i], leftType, ic->op);
594 if (ic->op == RRC || ic->op == RLC || ic->op == LEFT_OP || ic->op == RIGHT_OP)
596 sym_link *type = operandType (IC_LEFT (ic));
598 if (IS_INTEGRAL (type) && getSize (type) > port->support.shift && port->support.shift >= 0)
600 convilong (ic, ebbs[i], type, ic->op);
607 /*-----------------------------------------------------------------*/
608 /* isLocalWithoutDef - return 1 if sym might be used without a */
610 /*-----------------------------------------------------------------*/
612 isLocalWithoutDef (symbol * sym)
617 if (IS_STATIC (sym->etype))
620 if (IS_VOLATILE (sym->type))
626 if (IS_AGGREGATE (sym->type))
635 /*-----------------------------------------------------------------*/
636 /* replaceRegEqv - replace all local variables with their reqv */
637 /*-----------------------------------------------------------------*/
639 replaceRegEqv (eBBlock ** ebbs, int count)
643 /* Update the symbols' def bitvector so we know if there is */
644 /* a defining iCode or not. Only replace a local variable */
645 /* with its register equivalent if there is a defining iCode; */
646 /* otherwise, the port's register allocater may choke. */
647 cseAllBlocks (ebbs, count, TRUE);
649 for (i = 0; i < count; i++)
654 for (ic = ebbs[i]->sch; ic; ic = ic->next)
663 IS_TRUE_SYMOP (IC_COND (ic)) &&
664 isLocalWithoutDef (OP_SYMBOL (IC_COND (ic))))
666 werrorfl (ic->filename, ic->lineno,
668 OP_SYMBOL (IC_COND (ic))->name);
669 OP_REQV (IC_COND (ic)) = NULL;
670 OP_SYMBOL (IC_COND (ic))->allocreq = 1;
673 if (IS_TRUE_SYMOP (IC_COND (ic)) &&
674 OP_REQV (IC_COND (ic)))
675 IC_COND (ic) = opFromOpWithDU (OP_REQV (IC_COND (ic)),
676 OP_SYMBOL (IC_COND (ic))->defs,
677 OP_SYMBOL (IC_COND (ic))->uses);
683 if (ic->op == JUMPTABLE)
685 if (IC_JTCOND (ic) &&
686 IS_TRUE_SYMOP (IC_JTCOND (ic)) &&
687 isLocalWithoutDef (OP_SYMBOL (IC_JTCOND (ic))))
689 werrorfl (ic->filename, ic->lineno,
691 OP_SYMBOL (IC_JTCOND (ic))->name);
692 OP_REQV (IC_JTCOND (ic)) = NULL;
693 OP_SYMBOL (IC_JTCOND (ic))->allocreq = 1;
696 if (IS_TRUE_SYMOP (IC_JTCOND (ic)) &&
697 OP_REQV (IC_JTCOND (ic)))
698 IC_JTCOND (ic) = opFromOpWithDU (OP_REQV (IC_JTCOND (ic)),
699 OP_SYMBOL (IC_JTCOND (ic))->defs,
700 OP_SYMBOL (IC_JTCOND (ic))->uses);
704 if (ic->op == RECEIVE)
706 if (OP_SYMBOL (IC_RESULT (ic))->addrtaken)
707 OP_SYMBOL (IC_RESULT (ic))->isspilt = 1;
711 if (IC_RESULT (ic) &&
712 IS_TRUE_SYMOP (IC_RESULT (ic)) &&
713 OP_REQV (IC_RESULT (ic)))
715 if (POINTER_SET (ic))
717 IC_RESULT (ic) = opFromOpWithDU (OP_REQV (IC_RESULT (ic)),
718 OP_SYMBOL (IC_RESULT (ic))->defs,
719 OP_SYMBOL (IC_RESULT (ic))->uses);
720 IC_RESULT (ic)->isaddr = 1;
723 IC_RESULT (ic) = opFromOpWithDU (OP_REQV (IC_RESULT (ic)),
724 OP_SYMBOL (IC_RESULT (ic))->defs,
725 OP_SYMBOL (IC_RESULT (ic))->uses);
729 IS_TRUE_SYMOP (IC_RIGHT (ic)) &&
730 isLocalWithoutDef (OP_SYMBOL (IC_RIGHT (ic))))
732 werrorfl (ic->filename, ic->lineno,
734 OP_SYMBOL (IC_RIGHT (ic))->name);
735 OP_REQV (IC_RIGHT (ic)) = NULL;
736 OP_SYMBOL (IC_RIGHT (ic))->allocreq = 1;
740 IS_TRUE_SYMOP (IC_RIGHT (ic)) &&
741 OP_REQV (IC_RIGHT (ic)))
743 IC_RIGHT (ic) = opFromOpWithDU (OP_REQV (IC_RIGHT (ic)),
744 OP_SYMBOL (IC_RIGHT (ic))->defs,
745 OP_SYMBOL (IC_RIGHT (ic))->uses);
746 IC_RIGHT (ic)->isaddr = 0;
750 IS_TRUE_SYMOP (IC_LEFT (ic)) &&
751 isLocalWithoutDef (OP_SYMBOL (IC_LEFT (ic))))
753 werrorfl (ic->filename, ic->lineno,
755 OP_SYMBOL (IC_LEFT (ic))->name);
756 OP_REQV (IC_LEFT (ic)) = NULL;
757 OP_SYMBOL (IC_LEFT (ic))->allocreq = 1;
761 IS_TRUE_SYMOP (IC_LEFT (ic)) &&
762 OP_REQV (IC_LEFT (ic)))
764 IC_LEFT (ic) = opFromOpWithDU (OP_REQV (IC_LEFT (ic)),
765 OP_SYMBOL (IC_LEFT (ic))->defs,
766 OP_SYMBOL (IC_LEFT (ic))->uses);
767 IC_LEFT (ic)->isaddr = 0;
773 /*-----------------------------------------------------------------*/
774 /* killDeadCode - eliminates dead assignments */
775 /*-----------------------------------------------------------------*/
777 killDeadCode (eBBlock ** ebbs, int count)
784 /* basic algorithm :- */
785 /* first the exclusion rules :- */
786 /* 1. if result is a global or volatile then skip */
787 /* 2. if assignment and result is a temp & isaddr then skip */
788 /* since this means array & pointer access, will be taken */
789 /* care of by alias analysis. */
790 /* 3. if the result is used in the remainder of the block skip */
791 /* 4. if this definition does not reach the end of the block */
792 /* i.e. the result is not present in the outExprs then KILL */
793 /* 5. if it reaches the end of block & is used by some success */
796 /* this whole process is carried on iteratively till no change */
801 /* for all blocks do */
802 for (i = 0; i < count; i++)
806 /* for all instructions in the block do */
807 for (ic = ebbs[i]->sch; ic; ic = ic->next)
815 ic->op == DUMMY_READ_VOLATILE ||
816 ic->op == CRITICAL ||
817 ic->op == ENDCRITICAL)
820 /* Since both IFX & JUMPTABLE (in SKIP_IC) have been tested for */
821 /* it is now safe to assume IC_LEFT, IC_RIGHT, & IC_RESULT are */
824 /* if the result is volatile then continue */
825 if (IC_RESULT (ic) && isOperandVolatile (IC_RESULT (ic), FALSE))
828 /* if the result is a temp & isaddr then skip */
829 if (IC_RESULT (ic) && POINTER_SET (ic))
832 if (POINTER_GET (ic) && IS_VOLATILE (operandType (IC_LEFT (ic))->next))
835 /* if the result is used in the remainder of the */
836 /* block then skip */
837 if (usedInRemaining (IC_RESULT (ic), ic->next))
840 /* does this definition reach the end of the block
841 or the usage is zero then we can kill */
842 if (!bitVectBitValue (ebbs[i]->outDefs, ic->key))
843 kill = 1; /* if not we can kill it */
846 /* if this is a global variable or function parameter */
847 /* we cannot kill anyway */
848 if (isOperandGlobal (IC_RESULT (ic)) ||
849 (OP_SYMBOL (IC_RESULT (ic))->_isparm &&
850 !OP_SYMBOL (IC_RESULT (ic))->ismyparm))
853 /* if we are sure there are no usages */
854 if (bitVectIsZero (OP_USES (IC_RESULT (ic))))
860 /* reset visited flag */
861 for (j = 0; j < count; ebbs[j++]->visited = 0);
863 /* find out if this definition is alive */
864 if (applyToSet (ebbs[i]->succList,
873 /* kill this one if required */
876 bool volLeft = IS_SYMOP (IC_LEFT (ic))
877 && isOperandVolatile (IC_LEFT (ic), FALSE);
878 bool volRight = IS_SYMOP (IC_RIGHT (ic))
879 && isOperandVolatile (IC_RIGHT (ic), FALSE);
881 /* a dead address-of operation should die, even if volatile */
882 if (ic->op == ADDRESS_OF)
885 if (ic->next && ic->seqPoint == ic->next->seqPoint
886 && (ic->next->op == '+' || ic->next->op == '-'))
888 if (isOperandEqual (IC_LEFT(ic), IC_LEFT(ic->next))
889 || isOperandEqual (IC_LEFT(ic), IC_RIGHT(ic->next)))
891 if (isOperandEqual (IC_RIGHT(ic), IC_LEFT(ic->next))
892 || isOperandEqual (IC_RIGHT(ic), IC_RIGHT(ic->next)))
899 /* now delete from defUseSet */
900 deleteItemIf (&ebbs[i]->outExprs, ifDiCodeIsX, ic);
901 bitVectUnSetBit (ebbs[i]->outDefs, ic->key);
903 /* and defset of the block */
904 bitVectUnSetBit (ebbs[i]->defSet, ic->key);
906 /* delete the result */
907 IC_RESULT (ic) = NULL;
909 if (volLeft || volRight)
911 /* something is volatile, so keep the iCode */
912 /* and change the operator instead */
913 ic->op = DUMMY_READ_VOLATILE;
915 /* keep only the volatile operands */
919 IC_RIGHT (ic) = NULL;
923 /* nothing is volatile, eliminate the iCode */
924 remiCodeFromeBBlock (ebbs[i], ic);
926 /* for the left & right remove the usage */
927 if (IS_SYMOP (IC_LEFT (ic)))
928 bitVectUnSetBit (OP_USES (IC_LEFT (ic)), ic->key);
930 if (IS_SYMOP (IC_RIGHT (ic)))
931 bitVectUnSetBit (OP_USES (IC_RIGHT (ic)), ic->key);
935 } /* end of all instructions */
937 if (!ebbs[i]->sch && !ebbs[i]->noPath)
938 disconBBlock (ebbs[i], ebbs, count);
940 } /* end of for all blocks */
944 } /* end of while(1) */
949 /*-----------------------------------------------------------------*/
950 /* printCyclomatic - prints the cyclomatic information */
951 /*-----------------------------------------------------------------*/
953 printCyclomatic (eBBlock ** ebbs, int count)
955 int nEdges = elementsInSet (graphEdges);
958 for (i = 0; i < count; i++)
959 nNodes += (!ebbs[i]->noPath);
961 /* print the information */
962 werror (I_CYCLOMATIC, currFunc->name, nEdges, nNodes, nEdges - nNodes + 2);
965 /*-----------------------------------------------------------------*/
966 /* discardDeadParamReceives - remove any RECEIVE opcodes which */
967 /* refer to dead variables. */
968 /*-----------------------------------------------------------------*/
970 discardDeadParamReceives (eBBlock ** ebbs, int count)
976 for (i = 0; i < count; i++)
978 for (ic = ebbs[i]->sch; ic; ic = ic->next)
980 if (ic->op == RECEIVE)
982 if (IC_RESULT (ic) && OP_SYMBOL (IC_RESULT (ic))
983 && !OP_SYMBOL (IC_RESULT (ic))->used)
986 fprintf (stderr, "discarding dead receive for %s\n",
987 OP_SYMBOL (IC_RESULT (ic))->name);
989 dummyIcode.next = ic->next;
990 remiCodeFromeBBlock (ebbs[i], ic);
998 /*-----------------------------------------------------------------*/
999 /* eBBlockFromiCode - creates extended basic blocks from iCode */
1000 /* will return an array of eBBlock pointers */
1001 /*-----------------------------------------------------------------*/
1003 eBBlockFromiCode (iCode * ic)
1005 eBBlock **ebbs = NULL;
1013 /* if nothing passed then return nothing */
1020 /* optimize the chain for labels & gotos
1021 this will eliminate redundant labels and
1022 will change jump to jumps by jumps */
1023 ic = iCodeLabelOptimize (ic);
1025 /* break it down into basic blocks */
1026 ebbs = iCodeBreakDown (ic, &count);
1029 /* hash the iCode keys so that we can quickly index */
1030 /* them in the rest of the optimization steps */
1031 setToNull ((void *) &iCodehTab);
1032 iCodehTab = newHashTable (iCodeKey);
1033 hashiCodeKeys (ebbs, count);
1035 /* compute the control flow */
1036 computeControlFlow (ebbs, count, 0);
1038 /* dumpraw if asked for */
1039 if (options.dump_raw)
1040 dumpEbbsToFileExt (DUMP_RAW0, ebbs, count);
1042 /* replace the local variables with their
1043 register equivalents : the liveRange computation
1044 along with the register allocation will determine
1045 if it finally stays in the registers */
1046 replaceRegEqv (ebbs, count);
1048 /* create loop regions */
1049 loops = createLoopRegions (ebbs, count);
1051 /* dumpraw if asked for */
1052 if (options.dump_raw)
1053 dumpEbbsToFileExt (DUMP_RAW1, ebbs, count);
1055 /* do common subexpression elimination for each block */
1056 change = cseAllBlocks (ebbs, saveCount, FALSE);
1058 /* dumpraw if asked for */
1059 if (options.dump_raw)
1060 dumpEbbsToFileExt (DUMP_CSE, ebbs, count);
1062 /* compute the data flow */
1063 computeDataFlow (ebbs, saveCount);
1065 /* dumpraw if asked for */
1066 if (options.dump_raw)
1067 dumpEbbsToFileExt (DUMP_DFLOW, ebbs, count);
1069 /* global common subexpression elimination */
1070 if (optimize.global_cse)
1072 change += cseAllBlocks (ebbs, saveCount, FALSE);
1073 if (options.dump_gcse)
1074 dumpEbbsToFileExt (DUMP_GCSE, ebbs, saveCount);
1078 // compute the dataflow only
1079 assert(cseAllBlocks (ebbs, saveCount, TRUE)==0);
1081 /* kill dead code */
1082 kchange = killDeadCode (ebbs, saveCount);
1084 if (options.dump_kill)
1085 dumpEbbsToFileExt (DUMP_DEADCODE, ebbs, count);
1087 /* do loop optimizations */
1088 change += (lchange = loopOptimizations (loops, ebbs, count));
1089 if (options.dump_loop)
1090 dumpEbbsToFileExt (DUMP_LOOP, ebbs, count);
1092 /* recompute the data flow and apply global cse again
1093 if loops optimizations or dead code caused a change:
1094 loops will brings out of the loop which then may be
1095 available for use in the later blocks: dead code
1096 elimination could potentially disconnect some blocks
1097 conditional flow may be efected so we need to apply
1098 subexpression once more */
1099 if (lchange || kchange)
1101 computeDataFlow (ebbs, saveCount);
1102 change += cseAllBlocks (ebbs, saveCount, FALSE);
1103 if (options.dump_loop)
1104 dumpEbbsToFileExt (DUMP_LOOPG, ebbs, count);
1106 /* if loop optimizations caused a change then do
1107 dead code elimination once more : this will
1108 get rid of the extra assignments to the induction
1109 variables created during loop optimizations */
1110 killDeadCode (ebbs, saveCount);
1112 if (options.dump_loop)
1113 dumpEbbsToFileExt (DUMP_LOOPD, ebbs, count);
1117 /* sort it back by block number */
1118 qsort (ebbs, saveCount, sizeof (eBBlock *), bbNumCompare);
1120 if (!options.lessPedantic) {
1121 // this is a good place to check missing return values
1123 // the user is on his own with naked functions...
1124 if (!IS_VOID(currFunc->etype)
1125 && !FUNC_ISNAKED(currFunc->type)) {
1127 // make sure all predecessors of the last block end in a return
1128 for (bp=setFirstItem(ebbs[saveCount-1]->predList);
1130 bp=setNextItem(ebbs[saveCount-1]->predList)) {
1131 if (bp->ech->op != RETURN) {
1132 werrorfl (bp->ech->filename, bp->ech->lineno,
1133 W_VOID_FUNC, currFunc->name);
1140 /* if cyclomatic info requested then print it */
1141 if (options.cyclomatic)
1142 printCyclomatic (ebbs, saveCount);
1144 /* convert operations with support routines
1145 written in C to function calls : Iam doing
1146 this at this point since I want all the
1147 operations to be as they are for optimzations */
1148 convertToFcall (ebbs, count);
1150 /* compute the live ranges */
1151 computeLiveRanges (ebbs, count);
1153 if (options.dump_range)
1154 dumpEbbsToFileExt (DUMP_RANGE, ebbs, count);
1156 /* Now that we have the live ranges, discard parameter
1157 * receives for unused parameters.
1159 discardDeadParamReceives (ebbs, count);
1161 /* allocate registers & generate code */
1162 port->assignRegisters (ebbs, count);
1164 /* throw away blocks */
1165 setToNull ((void *) &graphEdges);
1172 /* (add-hook 'c-mode-hook (lambda () (setq c-basic-offset 4))) */