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;
179 addiCodeToeBBlock (ebp, newic, ip);
182 /*-----------------------------------------------------------------*/
183 /* cnvToFloatCast - converts casts to floats to function calls */
184 /*-----------------------------------------------------------------*/
186 cnvToFloatCast (iCode * ic, eBBlock * ebp)
190 sym_link *type = operandType (IC_RIGHT (ic));
191 int linenno = ic->lineno;
196 /* remove it from the iCode */
197 remiCodeFromeBBlock (ebp, ic);
198 /* depending on the type */
199 for (bwd = 0; bwd < 3; bwd++)
201 for (su = 0; su < 2; su++)
203 if (compareType (type, __multypes[bwd][su]) == 1)
205 func = __conv[0][bwd][su];
213 /* if float support routines NOT compiled as reentrant */
214 if (!options.float_rent)
217 if (IS_REGPARM (FUNC_ARGS(func->type)->etype))
219 newic = newiCode (SEND, IC_RIGHT (ic), NULL);
220 newic->argreg = SPEC_ARGREG(FUNC_ARGS(func->type)->etype);
224 newic = newiCode ('=', NULL, IC_RIGHT (ic));
225 IC_RESULT (newic) = operandFromValue (FUNC_ARGS(func->type));
227 addiCodeToeBBlock (ebp, newic, ip);
228 newic->lineno = linenno;
234 if (IS_REGPARM (FUNC_ARGS(func->type)->etype)) {
235 newic = newiCode (SEND, IC_RIGHT (ic), NULL);
236 newic->argreg = SPEC_ARGREG(FUNC_ARGS(func->type)->etype);
240 newic = newiCode (IPUSH, IC_RIGHT (ic), NULL);
242 bytesPushed += getSize(operandType(IC_RIGHT(ic)));
244 addiCodeToeBBlock (ebp, newic, ip);
245 newic->lineno = linenno;
250 newic = newiCode (CALL, operandFromSymbol (func), NULL);
251 IC_RESULT (newic) = IC_RESULT (ic);
252 newic->parmBytes+=bytesPushed;
253 addiCodeToeBBlock (ebp, newic, ip);
254 newic->lineno = linenno;
258 /*-----------------------------------------------------------------*/
259 /* cnvFromFloatCast - converts casts From floats to function calls */
260 /*-----------------------------------------------------------------*/
262 cnvFromFloatCast (iCode * ic, eBBlock * ebp)
266 sym_link *type = operandType (IC_LEFT (ic));
267 int lineno = ic->lineno;
272 /* remove it from the iCode */
273 remiCodeFromeBBlock (ebp, ic);
275 /* depending on the type */
276 for (bwd = 0; bwd < 3; bwd++)
278 for (su = 0; su < 2; su++)
280 if (compareType (type, __multypes[bwd][su]) == 1)
282 func = __conv[1][bwd][su];
290 /* if float support routines NOT compiled as reentrant */
291 if (!options.float_rent)
294 if (IS_REGPARM (FUNC_ARGS(func->type)->etype)) {
295 newic = newiCode (SEND, IC_RIGHT (ic), NULL);
296 newic->argreg = SPEC_ARGREG(FUNC_ARGS(func->type)->etype);
300 newic = newiCode ('=', NULL, IC_RIGHT (ic));
301 IC_RESULT (newic) = operandFromValue (FUNC_ARGS(func->type));
303 addiCodeToeBBlock (ebp, newic, ip);
304 newic->lineno = lineno;
311 if (IS_REGPARM (FUNC_ARGS(func->type)->etype)) {
312 newic = newiCode (SEND, IC_RIGHT (ic), NULL);
313 newic->argreg = SPEC_ARGREG(FUNC_ARGS(func->type)->etype);
317 newic = newiCode (IPUSH, IC_RIGHT (ic), NULL);
319 bytesPushed += getSize(operandType(IC_RIGHT(ic)));
321 addiCodeToeBBlock (ebp, newic, ip);
322 newic->lineno = lineno;
327 newic = newiCode (CALL, operandFromSymbol (func), NULL);
328 IC_RESULT (newic) = IC_RESULT (ic);
329 newic->parmBytes+=bytesPushed;
330 addiCodeToeBBlock (ebp, newic, ip);
331 newic->lineno = lineno;
335 extern operand *geniCodeRValue (operand *, bool);
337 /*-----------------------------------------------------------------*/
338 /* convilong - converts int or long mults or divs to fcalls */
339 /*-----------------------------------------------------------------*/
341 convilong (iCode * ic, eBBlock * ebp, sym_link * type, int op)
344 iCode *ip = ic->next;
346 int lineno = ic->lineno;
351 // Easy special case which avoids function call: modulo by a literal power
352 // of two can be replaced by a bitwise AND.
353 if (op == '%' && isOperandLiteral(IC_RIGHT(ic)))
355 unsigned litVal = (unsigned)(operandLitValue(IC_RIGHT(ic)));
357 // See if literal value is a power of 2.
358 while (litVal && !(litVal & 1))
364 // discard first high bit set.
371 IC_RIGHT(ic) = operandFromLit(operandLitValue(IC_RIGHT(ic)) - 1);
376 remiCodeFromeBBlock (ebp, ic);
379 /* depending on the type */
380 for (bwd = 0; bwd < 3; bwd++)
382 for (su = 0; su < 2; su++)
384 if (compareType (type, __multypes[bwd][su]) == 1)
387 func = __muldiv[0][bwd][su];
389 func = __muldiv[1][bwd][su];
391 func = __muldiv[2][bwd][su];
393 func = __rlrr[1][bwd][su];
395 func = __rlrr[0][bwd][su];
396 else if (op == RIGHT_OP)
397 func = __rlrr[1][bwd][su];
398 else if (op == LEFT_OP)
399 func = __rlrr[0][bwd][su];
408 /* if int & long support routines NOT compiled as reentrant */
409 if (!options.intlong_rent)
412 if (IS_REGPARM (FUNC_ARGS(func->type)->etype)) {
413 newic = newiCode (SEND, IC_LEFT (ic), NULL);
414 newic->argreg = SPEC_ARGREG(FUNC_ARGS(func->type)->etype);
418 newic = newiCode ('=', NULL, IC_LEFT (ic));
419 IC_RESULT (newic) = operandFromValue (FUNC_ARGS(func->type));
421 addiCodeToeBBlock (ebp, newic, ip);
422 newic->lineno = lineno;
425 if (IS_REGPARM (FUNC_ARGS(func->type)->next->etype)) {
426 newic = newiCode (SEND, IC_RIGHT (ic), NULL);
427 newic->argreg = SPEC_ARGREG(FUNC_ARGS(func->type)->next->etype);
431 newic = newiCode ('=', NULL, IC_RIGHT (ic));
432 IC_RESULT (newic) = operandFromValue (FUNC_ARGS(func->type)->next);
434 addiCodeToeBBlock (ebp, newic, ip);
435 newic->lineno = lineno;
440 /* compiled as reentrant then push */
442 if (IS_REGPARM (FUNC_ARGS(func->type)->next->etype))
444 newic = newiCode (SEND, IC_RIGHT (ic), NULL);
445 newic->argreg = SPEC_ARGREG(FUNC_ARGS(func->type)->next->etype);
449 newic = newiCode (IPUSH, IC_RIGHT (ic), NULL);
452 bytesPushed += getSize(operandType(IC_RIGHT(ic)));
454 addiCodeToeBBlock (ebp, newic, ip);
455 newic->lineno = lineno;
457 /* insert push left */
458 if (IS_REGPARM (FUNC_ARGS(func->type)->etype))
460 newic = newiCode (SEND, IC_LEFT (ic), NULL);
461 newic->argreg = SPEC_ARGREG(FUNC_ARGS(func->type)->etype);
465 newic = newiCode (IPUSH, IC_LEFT (ic), NULL);
468 bytesPushed += getSize(operandType(IC_LEFT(ic)));
470 addiCodeToeBBlock (ebp, newic, ip);
471 newic->lineno = lineno;
476 newic = newiCode (CALL, operandFromSymbol (func), NULL);
477 IC_RESULT (newic) = IC_RESULT (ic);
478 newic->lineno = lineno;
479 newic->parmBytes+=bytesPushed; // to clear the stack after the call
480 addiCodeToeBBlock (ebp, newic, ip);
483 /*-----------------------------------------------------------------*/
484 /* convertToFcall - converts some operations to fcalls */
485 /*-----------------------------------------------------------------*/
487 convertToFcall (eBBlock ** ebbs, int count)
491 /* for all blocks do */
492 for (i = 0; i < count; i++)
496 /* for all instructions in the block do */
497 for (ic = ebbs[i]->sch; ic; ic = ic->next)
500 /* floating point operations are
501 converted to function calls */
502 if ((IS_CONDITIONAL (ic) ||
503 IS_ARITHMETIC_OP (ic)) &&
504 (IS_FLOAT (operandType (IC_RIGHT (ic)))))
507 cnvToFcall (ic, ebbs[i]);
510 /* casting is a little different */
513 if (IS_FLOAT (operandType (IC_RIGHT (ic))))
514 cnvFromFloatCast (ic, ebbs[i]);
515 else if (IS_FLOAT (operandType (IC_LEFT (ic))))
516 cnvToFloatCast (ic, ebbs[i]);
519 /* if long / int mult or divide or mod */
520 if (ic->op == '*' || ic->op == '/' || ic->op == '%')
522 sym_link *leftType = operandType (IC_LEFT (ic));
524 if (IS_INTEGRAL (leftType) && getSize (leftType) > port->support.muldiv)
526 sym_link *rightType = operandType (IC_RIGHT (ic));
528 if (port->hasNativeMulFor != NULL &&
529 port->hasNativeMulFor (ic, leftType, rightType))
531 /* Leave as native */
535 convilong (ic, ebbs[i], leftType, ic->op);
540 if (ic->op == RRC || ic->op == RLC || ic->op == LEFT_OP || ic->op == RIGHT_OP)
542 sym_link *type = operandType (IC_LEFT (ic));
544 if (IS_INTEGRAL (type) && getSize (type) > port->support.shift && port->support.shift >= 0)
546 convilong (ic, ebbs[i], type, ic->op);
553 /*-----------------------------------------------------------------*/
554 /* isLocalWithoutDef - return 1 if sym might be used without a */
556 /*-----------------------------------------------------------------*/
558 isLocalWithoutDef (symbol * sym)
563 if (IS_STATIC (sym->etype))
566 if (IS_VOLATILE (sym->type))
572 if (IS_AGGREGATE (sym->type))
581 /*-----------------------------------------------------------------*/
582 /* replaceRegEqv - replace all local variables with their reqv */
583 /*-----------------------------------------------------------------*/
585 replaceRegEqv (eBBlock ** ebbs, int count)
589 /* Update the symbols' def bitvector so we know if there is */
590 /* a defining iCode or not. Only replace a local variable */
591 /* with its register equivalent if there is a defining iCode; */
592 /* otherwise, the port's register allocater may choke. */
593 cseAllBlocks (ebbs, count, TRUE);
595 for (i = 0; i < count; i++)
600 for (ic = ebbs[i]->sch; ic; ic = ic->next)
609 IS_TRUE_SYMOP (IC_COND (ic)) &&
610 isLocalWithoutDef (OP_SYMBOL (IC_COND (ic))))
612 werrorfl (ic->filename, ic->lineno,
614 OP_SYMBOL (IC_COND (ic))->name);
615 OP_REQV (IC_COND (ic)) = NULL;
616 OP_SYMBOL (IC_COND (ic))->allocreq = 1;
619 if (IS_TRUE_SYMOP (IC_COND (ic)) &&
620 OP_REQV (IC_COND (ic)))
621 IC_COND (ic) = opFromOpWithDU (OP_REQV (IC_COND (ic)),
622 OP_SYMBOL (IC_COND (ic))->defs,
623 OP_SYMBOL (IC_COND (ic))->uses);
629 if (ic->op == JUMPTABLE)
631 if (IC_JTCOND (ic) &&
632 IS_TRUE_SYMOP (IC_JTCOND (ic)) &&
633 isLocalWithoutDef (OP_SYMBOL (IC_JTCOND (ic))))
635 werrorfl (ic->filename, ic->lineno,
637 OP_SYMBOL (IC_JTCOND (ic))->name);
638 OP_REQV (IC_JTCOND (ic)) = NULL;
639 OP_SYMBOL (IC_JTCOND (ic))->allocreq = 1;
642 if (IS_TRUE_SYMOP (IC_JTCOND (ic)) &&
643 OP_REQV (IC_JTCOND (ic)))
644 IC_JTCOND (ic) = opFromOpWithDU (OP_REQV (IC_JTCOND (ic)),
645 OP_SYMBOL (IC_JTCOND (ic))->defs,
646 OP_SYMBOL (IC_JTCOND (ic))->uses);
650 if (ic->op == RECEIVE)
652 if (OP_SYMBOL (IC_RESULT (ic))->addrtaken)
653 OP_SYMBOL (IC_RESULT (ic))->isspilt = 1;
657 if (IC_RESULT (ic) &&
658 IS_TRUE_SYMOP (IC_RESULT (ic)) &&
659 OP_REQV (IC_RESULT (ic)))
661 if (POINTER_SET (ic))
663 IC_RESULT (ic) = opFromOpWithDU (OP_REQV (IC_RESULT (ic)),
664 OP_SYMBOL (IC_RESULT (ic))->defs,
665 OP_SYMBOL (IC_RESULT (ic))->uses);
666 IC_RESULT (ic)->isaddr = 1;
669 IC_RESULT (ic) = opFromOpWithDU (OP_REQV (IC_RESULT (ic)),
670 OP_SYMBOL (IC_RESULT (ic))->defs,
671 OP_SYMBOL (IC_RESULT (ic))->uses);
675 IS_TRUE_SYMOP (IC_RIGHT (ic)) &&
676 isLocalWithoutDef (OP_SYMBOL (IC_RIGHT (ic))))
678 werrorfl (ic->filename, ic->lineno,
680 OP_SYMBOL (IC_RIGHT (ic))->name);
681 OP_REQV (IC_RIGHT (ic)) = NULL;
682 OP_SYMBOL (IC_RIGHT (ic))->allocreq = 1;
686 IS_TRUE_SYMOP (IC_RIGHT (ic)) &&
687 OP_REQV (IC_RIGHT (ic)))
689 IC_RIGHT (ic) = opFromOpWithDU (OP_REQV (IC_RIGHT (ic)),
690 OP_SYMBOL (IC_RIGHT (ic))->defs,
691 OP_SYMBOL (IC_RIGHT (ic))->uses);
692 IC_RIGHT (ic)->isaddr = 0;
696 IS_TRUE_SYMOP (IC_LEFT (ic)) &&
697 isLocalWithoutDef (OP_SYMBOL (IC_LEFT (ic))))
699 werrorfl (ic->filename, ic->lineno,
701 OP_SYMBOL (IC_LEFT (ic))->name);
702 OP_REQV (IC_LEFT (ic)) = NULL;
703 OP_SYMBOL (IC_LEFT (ic))->allocreq = 1;
707 IS_TRUE_SYMOP (IC_LEFT (ic)) &&
708 OP_REQV (IC_LEFT (ic)))
710 IC_LEFT (ic) = opFromOpWithDU (OP_REQV (IC_LEFT (ic)),
711 OP_SYMBOL (IC_LEFT (ic))->defs,
712 OP_SYMBOL (IC_LEFT (ic))->uses);
713 IC_LEFT (ic)->isaddr = 0;
719 /*-----------------------------------------------------------------*/
720 /* killDeadCode - eliminates dead assignments */
721 /*-----------------------------------------------------------------*/
723 killDeadCode (eBBlock ** ebbs, int count)
730 /* basic algorithm :- */
731 /* first the exclusion rules :- */
732 /* 1. if result is a global or volatile then skip */
733 /* 2. if assignment and result is a temp & isaddr then skip */
734 /* since this means array & pointer access, will be taken */
735 /* care of by alias analysis. */
736 /* 3. if the result is used in the remainder of the block skip */
737 /* 4. if this definition does not reach the end of the block */
738 /* i.e. the result is not present in the outExprs then KILL */
739 /* 5. if it reaches the end of block & is used by some success */
742 /* this whole process is carried on iteratively till no change */
747 /* for all blocks do */
748 for (i = 0; i < count; i++)
752 /* for all instructions in the block do */
753 for (ic = ebbs[i]->sch; ic; ic = ic->next)
761 ic->op == DUMMY_READ_VOLATILE ||
762 ic->op == CRITICAL ||
763 ic->op == ENDCRITICAL)
766 /* Since both IFX & JUMPTABLE (in SKIP_IC) have been tested for */
767 /* it is now safe to assume IC_LEFT, IC_RIGHT, & IC_RESULT are */
770 /* if the result is volatile then continue */
771 if (IC_RESULT (ic) && isOperandVolatile (IC_RESULT (ic), FALSE))
774 /* if the result is a temp & isaddr then skip */
775 if (IC_RESULT (ic) && POINTER_SET (ic))
778 if (POINTER_GET (ic) && IS_VOLATILE (operandType (IC_LEFT (ic))->next))
781 /* if the result is used in the remainder of the */
782 /* block then skip */
783 if (usedInRemaining (IC_RESULT (ic), ic->next))
786 /* does this definition reach the end of the block
787 or the usage is zero then we can kill */
788 if (!bitVectBitValue (ebbs[i]->outDefs, ic->key))
789 kill = 1; /* if not we can kill it */
792 /* if this is a global variable or function parameter */
793 /* we cannot kill anyway */
794 if (isOperandGlobal (IC_RESULT (ic)) ||
795 (OP_SYMBOL (IC_RESULT (ic))->_isparm &&
796 !OP_SYMBOL (IC_RESULT (ic))->ismyparm))
799 /* if we are sure there are no usages */
800 if (bitVectIsZero (OP_USES (IC_RESULT (ic))))
806 /* reset visited flag */
807 for (j = 0; j < count; ebbs[j++]->visited = 0);
809 /* find out if this definition is alive */
810 if (applyToSet (ebbs[i]->succList,
819 /* kill this one if required */
822 bool volLeft = IS_SYMOP (IC_LEFT (ic))
823 && isOperandVolatile (IC_LEFT (ic), FALSE);
824 bool volRight = IS_SYMOP (IC_RIGHT (ic))
825 && isOperandVolatile (IC_RIGHT (ic), FALSE);
828 if (ic->next && ic->seqPoint == ic->next->seqPoint
829 && (ic->next->op == '+' || ic->next->op == '-'))
831 if (isOperandEqual (IC_LEFT(ic), IC_LEFT(ic->next))
832 || isOperandEqual (IC_LEFT(ic), IC_RIGHT(ic->next)))
834 if (isOperandEqual (IC_RIGHT(ic), IC_LEFT(ic->next))
835 || isOperandEqual (IC_RIGHT(ic), IC_RIGHT(ic->next)))
842 /* now delete from defUseSet */
843 deleteItemIf (&ebbs[i]->outExprs, ifDiCodeIsX, ic);
844 bitVectUnSetBit (ebbs[i]->outDefs, ic->key);
846 /* and defset of the block */
847 bitVectUnSetBit (ebbs[i]->defSet, ic->key);
849 /* delete the result */
850 IC_RESULT (ic) = NULL;
852 if (volLeft || volRight)
854 /* something is volatile, so keep the iCode */
855 /* and change the operator instead */
856 ic->op = DUMMY_READ_VOLATILE;
858 /* keep only the volatile operands */
862 IC_RIGHT (ic) = NULL;
866 /* nothing is volatile, eliminate the iCode */
867 remiCodeFromeBBlock (ebbs[i], ic);
869 /* for the left & right remove the usage */
870 if (IS_SYMOP (IC_LEFT (ic)))
871 bitVectUnSetBit (OP_USES (IC_LEFT (ic)), ic->key);
873 if (IS_SYMOP (IC_RIGHT (ic)))
874 bitVectUnSetBit (OP_USES (IC_RIGHT (ic)), ic->key);
878 } /* end of all instructions */
880 if (!ebbs[i]->sch && !ebbs[i]->noPath)
881 disconBBlock (ebbs[i], ebbs, count);
883 } /* end of for all blocks */
887 } /* end of while(1) */
892 /*-----------------------------------------------------------------*/
893 /* printCyclomatic - prints the cyclomatic information */
894 /*-----------------------------------------------------------------*/
896 printCyclomatic (eBBlock ** ebbs, int count)
898 int nEdges = elementsInSet (graphEdges);
901 for (i = 0; i < count; i++)
902 nNodes += (!ebbs[i]->noPath);
904 /* print the information */
905 werror (I_CYCLOMATIC, currFunc->name, nEdges, nNodes, nEdges - nNodes + 2);
908 /*-----------------------------------------------------------------*/
909 /* discardDeadParamReceives - remove any RECEIVE opcodes which */
910 /* refer to dead variables. */
911 /*-----------------------------------------------------------------*/
913 discardDeadParamReceives (eBBlock ** ebbs, int count)
919 for (i = 0; i < count; i++)
921 for (ic = ebbs[i]->sch; ic; ic = ic->next)
923 if (ic->op == RECEIVE)
925 if (IC_RESULT (ic) && OP_SYMBOL (IC_RESULT (ic))
926 && !OP_SYMBOL (IC_RESULT (ic))->used)
929 fprintf (stderr, "discarding dead receive for %s\n",
930 OP_SYMBOL (IC_RESULT (ic))->name);
932 dummyIcode.next = ic->next;
933 remiCodeFromeBBlock (ebbs[i], ic);
941 /*-----------------------------------------------------------------*/
942 /* eBBlockFromiCode - creates extended basic blocks from iCode */
943 /* will return an array of eBBlock pointers */
944 /*-----------------------------------------------------------------*/
946 eBBlockFromiCode (iCode * ic)
948 eBBlock **ebbs = NULL;
956 /* if nothing passed then return nothing */
963 /* optimize the chain for labels & gotos
964 this will eliminate redundant labels and
965 will change jump to jumps by jumps */
966 ic = iCodeLabelOptimize (ic);
968 /* break it down into basic blocks */
969 ebbs = iCodeBreakDown (ic, &count);
972 /* hash the iCode keys so that we can quickly index */
973 /* them in the rest of the optimization steps */
974 setToNull ((void *) &iCodehTab);
975 iCodehTab = newHashTable (iCodeKey);
976 hashiCodeKeys (ebbs, count);
978 /* compute the control flow */
979 computeControlFlow (ebbs, count, 0);
981 /* dumpraw if asked for */
982 if (options.dump_raw)
983 dumpEbbsToFileExt (DUMP_RAW0, ebbs, count);
985 /* replace the local variables with their
986 register equivalents : the liveRange computation
987 along with the register allocation will determine
988 if it finally stays in the registers */
989 replaceRegEqv (ebbs, count);
991 /* create loop regions */
992 loops = createLoopRegions (ebbs, count);
994 /* dumpraw if asked for */
995 if (options.dump_raw)
996 dumpEbbsToFileExt (DUMP_RAW1, ebbs, count);
998 /* do common subexpression elimination for each block */
999 change = cseAllBlocks (ebbs, saveCount, FALSE);
1001 /* dumpraw if asked for */
1002 if (options.dump_raw)
1003 dumpEbbsToFileExt (DUMP_CSE, ebbs, count);
1005 /* compute the data flow */
1006 computeDataFlow (ebbs, saveCount);
1008 /* dumpraw if asked for */
1009 if (options.dump_raw)
1010 dumpEbbsToFileExt (DUMP_DFLOW, ebbs, count);
1012 /* global common subexpression elimination */
1013 if (optimize.global_cse)
1015 change += cseAllBlocks (ebbs, saveCount, FALSE);
1016 if (options.dump_gcse)
1017 dumpEbbsToFileExt (DUMP_GCSE, ebbs, saveCount);
1021 // compute the dataflow only
1022 assert(cseAllBlocks (ebbs, saveCount, TRUE)==0);
1024 /* kill dead code */
1025 kchange = killDeadCode (ebbs, saveCount);
1027 if (options.dump_kill)
1028 dumpEbbsToFileExt (DUMP_DEADCODE, ebbs, count);
1030 /* do loop optimizations */
1031 change += (lchange = loopOptimizations (loops, ebbs, count));
1032 if (options.dump_loop)
1033 dumpEbbsToFileExt (DUMP_LOOP, ebbs, count);
1035 /* recompute the data flow and apply global cse again
1036 if loops optimizations or dead code caused a change:
1037 loops will brings out of the loop which then may be
1038 available for use in the later blocks: dead code
1039 elimination could potentially disconnect some blocks
1040 conditional flow may be efected so we need to apply
1041 subexpression once more */
1042 if (lchange || kchange)
1044 computeDataFlow (ebbs, saveCount);
1045 change += cseAllBlocks (ebbs, saveCount, FALSE);
1046 if (options.dump_loop)
1047 dumpEbbsToFileExt (DUMP_LOOPG, ebbs, count);
1049 /* if loop optimizations caused a change then do
1050 dead code elimination once more : this will
1051 get rid of the extra assignments to the induction
1052 variables created during loop optimizations */
1053 killDeadCode (ebbs, saveCount);
1055 if (options.dump_loop)
1056 dumpEbbsToFileExt (DUMP_LOOPD, ebbs, count);
1060 /* sort it back by block number */
1061 qsort (ebbs, saveCount, sizeof (eBBlock *), bbNumCompare);
1063 if (!options.lessPedantic) {
1064 // this is a good place to check missing return values
1066 // the user is on his own with naked functions...
1067 if (!IS_VOID(currFunc->etype)
1068 && !FUNC_ISNAKED(currFunc->type)) {
1070 // make sure all predecessors of the last block end in a return
1071 for (bp=setFirstItem(ebbs[saveCount-1]->predList);
1073 bp=setNextItem(ebbs[saveCount-1]->predList)) {
1074 if (bp->ech->op != RETURN) {
1075 werrorfl (bp->ech->filename, bp->ech->lineno,
1076 W_VOID_FUNC, currFunc->name);
1083 /* if cyclomatic info requested then print it */
1084 if (options.cyclomatic)
1085 printCyclomatic (ebbs, saveCount);
1087 /* convert operations with support routines
1088 written in C to function calls : Iam doing
1089 this at this point since I want all the
1090 operations to be as they are for optimzations */
1091 convertToFcall (ebbs, count);
1093 /* compute the live ranges */
1094 computeLiveRanges (ebbs, count);
1096 if (options.dump_range)
1097 dumpEbbsToFileExt (DUMP_RANGE, ebbs, count);
1099 /* Now that we have the live ranges, discard parameter
1100 * receives for unused parameters.
1102 discardDeadParamReceives (ebbs, count);
1104 /* allocate registers & generate code */
1105 port->assignRegisters (ebbs, count);
1107 /* throw away blocks */
1108 setToNull ((void *) &graphEdges);
1115 /* (add-hook 'c-mode-hook (lambda () (setq c-basic-offset 4))) */