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);
154 addiCodeToeBBlock (ebp, newic, ip);
155 newic->lineno = lineno;
157 /* insert push left */
158 if (IS_REGPARM (FUNC_ARGS(func->type)->etype))
160 newic = newiCode (SEND, left, NULL);
161 newic->argreg = SPEC_ARGREG(FUNC_ARGS(func->type)->etype);
165 newic = newiCode (IPUSH, left, NULL);
169 addiCodeToeBBlock (ebp, newic, ip);
170 newic->lineno = lineno;
172 /* insert the call */
173 newic = newiCode (CALL, operandFromSymbol (func), NULL);
174 IC_RESULT (newic) = IC_RESULT (ic);
175 newic->lineno = lineno;
176 newic->parmBytes+=bytesPushed;
177 addiCodeToeBBlock (ebp, newic, ip);
180 /*-----------------------------------------------------------------*/
181 /* cnvToFloatCast - converts casts to floats to function calls */
182 /*-----------------------------------------------------------------*/
184 cnvToFloatCast (iCode * ic, eBBlock * ebp)
188 sym_link *type = operandType (IC_RIGHT (ic));
189 int linenno = ic->lineno;
193 /* remove it from the iCode */
194 remiCodeFromeBBlock (ebp, ic);
195 /* depending on the type */
196 for (bwd = 0; bwd < 3; bwd++)
198 for (su = 0; su < 2; su++)
200 if (compareType (type, __multypes[bwd][su]) == 1)
202 func = __conv[0][bwd][su];
210 /* if float support routines NOT compiled as reentrant */
211 if (!options.float_rent)
214 if (IS_REGPARM (FUNC_ARGS(func->type)->etype))
216 newic = newiCode (SEND, IC_RIGHT (ic), NULL);
217 newic->argreg = SPEC_ARGREG(FUNC_ARGS(func->type)->etype);
221 newic = newiCode ('=', NULL, IC_RIGHT (ic));
222 IC_RESULT (newic) = operandFromValue (FUNC_ARGS(func->type));
224 addiCodeToeBBlock (ebp, newic, ip);
225 newic->lineno = linenno;
231 if (IS_REGPARM (FUNC_ARGS(func->type)->etype)) {
232 newic = newiCode (SEND, IC_RIGHT (ic), NULL);
233 newic->argreg = SPEC_ARGREG(FUNC_ARGS(func->type)->etype);
237 newic = newiCode (IPUSH, IC_RIGHT (ic), NULL);
240 addiCodeToeBBlock (ebp, newic, ip);
241 newic->lineno = linenno;
246 newic = newiCode (CALL, operandFromSymbol (func), NULL);
247 IC_RESULT (newic) = IC_RESULT (ic);
248 addiCodeToeBBlock (ebp, newic, ip);
249 newic->lineno = linenno;
253 /*-----------------------------------------------------------------*/
254 /* cnvFromFloatCast - converts casts From floats to function calls */
255 /*-----------------------------------------------------------------*/
257 cnvFromFloatCast (iCode * ic, eBBlock * ebp)
261 sym_link *type = operandType (IC_LEFT (ic));
262 int lineno = ic->lineno;
266 /* remove it from the iCode */
267 remiCodeFromeBBlock (ebp, ic);
269 /* depending on the type */
270 for (bwd = 0; bwd < 3; bwd++)
272 for (su = 0; su < 2; su++)
274 if (compareType (type, __multypes[bwd][su]) == 1)
276 func = __conv[1][bwd][su];
284 /* if float support routines NOT compiled as reentrant */
285 if (!options.float_rent)
288 if (IS_REGPARM (FUNC_ARGS(func->type)->etype)) {
289 newic = newiCode (SEND, IC_RIGHT (ic), NULL);
290 newic->argreg = SPEC_ARGREG(FUNC_ARGS(func->type)->etype);
294 newic = newiCode ('=', NULL, IC_RIGHT (ic));
295 IC_RESULT (newic) = operandFromValue (FUNC_ARGS(func->type));
297 addiCodeToeBBlock (ebp, newic, ip);
298 newic->lineno = lineno;
305 if (IS_REGPARM (FUNC_ARGS(func->type)->etype)) {
306 newic = newiCode (SEND, IC_RIGHT (ic), NULL);
307 newic->argreg = SPEC_ARGREG(FUNC_ARGS(func->type)->etype);
311 newic = newiCode (IPUSH, IC_RIGHT (ic), NULL);
314 addiCodeToeBBlock (ebp, newic, ip);
315 newic->lineno = lineno;
320 newic = newiCode (CALL, operandFromSymbol (func), NULL);
321 IC_RESULT (newic) = IC_RESULT (ic);
322 addiCodeToeBBlock (ebp, newic, ip);
323 newic->lineno = lineno;
327 extern operand *geniCodeRValue (operand *, bool);
329 /*-----------------------------------------------------------------*/
330 /* convilong - converts int or long mults or divs to fcalls */
331 /*-----------------------------------------------------------------*/
333 convilong (iCode * ic, eBBlock * ebp, sym_link * type, int op)
336 iCode *ip = ic->next;
338 int lineno = ic->lineno;
343 // Easy special case which avoids function call: modulo by a literal power
344 // of two can be replaced by a bitwise AND.
345 if (op == '%' && isOperandLiteral(IC_RIGHT(ic)))
347 unsigned litVal = (unsigned)(operandLitValue(IC_RIGHT(ic)));
349 // See if literal value is a power of 2.
350 while (litVal && !(litVal & 1))
356 // discard first high bit set.
363 IC_RIGHT(ic) = operandFromLit(operandLitValue(IC_RIGHT(ic)) - 1);
368 remiCodeFromeBBlock (ebp, ic);
371 /* depending on the type */
372 for (bwd = 0; bwd < 3; bwd++)
374 for (su = 0; su < 2; su++)
376 if (compareType (type, __multypes[bwd][su]) == 1)
379 func = __muldiv[0][bwd][su];
381 func = __muldiv[1][bwd][su];
383 func = __muldiv[2][bwd][su];
385 func = __rlrr[1][bwd][su];
387 func = __rlrr[0][bwd][su];
388 else if (op == RIGHT_OP)
389 func = __rlrr[1][bwd][su];
390 else if (op == LEFT_OP)
391 func = __rlrr[0][bwd][su];
400 /* if int & long support routines NOT compiled as reentrant */
401 if (!options.intlong_rent)
404 if (IS_REGPARM (FUNC_ARGS(func->type)->etype)) {
405 newic = newiCode (SEND, IC_LEFT (ic), NULL);
406 newic->argreg = SPEC_ARGREG(FUNC_ARGS(func->type)->etype);
410 newic = newiCode ('=', NULL, IC_LEFT (ic));
411 IC_RESULT (newic) = operandFromValue (FUNC_ARGS(func->type));
413 addiCodeToeBBlock (ebp, newic, ip);
414 newic->lineno = lineno;
417 if (IS_REGPARM (FUNC_ARGS(func->type)->next->etype)) {
418 newic = newiCode (SEND, IC_RIGHT (ic), NULL);
419 newic->argreg = SPEC_ARGREG(FUNC_ARGS(func->type)->next->etype);
423 newic = newiCode ('=', NULL, IC_RIGHT (ic));
424 IC_RESULT (newic) = operandFromValue (FUNC_ARGS(func->type)->next);
426 addiCodeToeBBlock (ebp, newic, ip);
427 newic->lineno = lineno;
432 /* compiled as reentrant then push */
434 if (IS_REGPARM (FUNC_ARGS(func->type)->next->etype))
436 newic = newiCode (SEND, IC_RIGHT (ic), NULL);
437 newic->argreg = SPEC_ARGREG(FUNC_ARGS(func->type)->next->etype);
441 newic = newiCode (IPUSH, IC_RIGHT (ic), NULL);
444 bytesPushed += getSize(operandType(IC_RIGHT(ic)));
446 addiCodeToeBBlock (ebp, newic, ip);
447 newic->lineno = lineno;
449 /* insert push left */
450 if (IS_REGPARM (FUNC_ARGS(func->type)->etype))
452 newic = newiCode (SEND, IC_LEFT (ic), NULL);
453 newic->argreg = SPEC_ARGREG(FUNC_ARGS(func->type)->etype);
457 newic = newiCode (IPUSH, IC_LEFT (ic), NULL);
460 bytesPushed += getSize(operandType(IC_LEFT(ic)));
462 addiCodeToeBBlock (ebp, newic, ip);
463 newic->lineno = lineno;
468 newic = newiCode (CALL, operandFromSymbol (func), NULL);
469 IC_RESULT (newic) = IC_RESULT (ic);
470 newic->lineno = lineno;
471 newic->parmBytes+=bytesPushed; // to clear the stack after the call
472 addiCodeToeBBlock (ebp, newic, ip);
475 /*-----------------------------------------------------------------*/
476 /* convertToFcall - converts some operations to fcalls */
477 /*-----------------------------------------------------------------*/
479 convertToFcall (eBBlock ** ebbs, int count)
483 /* for all blocks do */
484 for (i = 0; i < count; i++)
488 /* for all instructions in the block do */
489 for (ic = ebbs[i]->sch; ic; ic = ic->next)
492 /* floating point operations are
493 converted to function calls */
494 if ((IS_CONDITIONAL (ic) ||
495 IS_ARITHMETIC_OP (ic)) &&
496 (IS_FLOAT (operandType (IC_RIGHT (ic)))))
499 cnvToFcall (ic, ebbs[i]);
502 /* casting is a little different */
505 if (IS_FLOAT (operandType (IC_RIGHT (ic))))
506 cnvFromFloatCast (ic, ebbs[i]);
507 else if (IS_FLOAT (operandType (IC_LEFT (ic))))
508 cnvToFloatCast (ic, ebbs[i]);
511 /* if long / int mult or divide or mod */
512 if (ic->op == '*' || ic->op == '/' || ic->op == '%')
514 sym_link *leftType = operandType (IC_LEFT (ic));
516 if (IS_INTEGRAL (leftType) && getSize (leftType) > port->support.muldiv)
518 sym_link *rightType = operandType (IC_RIGHT (ic));
520 if (port->hasNativeMulFor != NULL &&
521 port->hasNativeMulFor (ic, leftType, rightType))
523 /* Leave as native */
527 convilong (ic, ebbs[i], leftType, ic->op);
532 if (ic->op == RRC || ic->op == RLC || ic->op == LEFT_OP || ic->op == RIGHT_OP)
534 sym_link *type = operandType (IC_LEFT (ic));
536 if (IS_INTEGRAL (type) && getSize (type) > port->support.shift && port->support.shift >= 0)
538 convilong (ic, ebbs[i], type, ic->op);
545 /*-----------------------------------------------------------------*/
546 /* replaceRegEqv - replace all local variables with their reqv */
547 /*-----------------------------------------------------------------*/
549 replaceRegEqv (eBBlock ** ebbs, int count)
553 for (i = 0; i < count; i++)
558 for (ic = ebbs[i]->sch; ic; ic = ic->next)
567 if (IS_TRUE_SYMOP (IC_COND (ic)) &&
568 OP_REQV (IC_COND (ic)))
569 IC_COND (ic) = opFromOpWithDU (OP_REQV (IC_COND (ic)),
570 OP_SYMBOL (IC_COND (ic))->defs,
571 OP_SYMBOL (IC_COND (ic))->uses);
576 if (ic->op == JUMPTABLE)
578 if (IS_TRUE_SYMOP (IC_JTCOND (ic)) &&
579 OP_REQV (IC_JTCOND (ic)))
580 IC_JTCOND (ic) = opFromOpWithDU (OP_REQV (IC_JTCOND (ic)),
581 OP_SYMBOL (IC_JTCOND (ic))->defs,
582 OP_SYMBOL (IC_JTCOND (ic))->uses);
586 if (ic->op == RECEIVE)
588 if (OP_SYMBOL (IC_RESULT (ic))->addrtaken)
589 OP_SYMBOL (IC_RESULT (ic))->isspilt = 1;
593 if (IC_RESULT (ic) &&
594 IS_TRUE_SYMOP (IC_RESULT (ic)) &&
595 OP_REQV (IC_RESULT (ic)))
597 if (POINTER_SET (ic))
599 IC_RESULT (ic) = opFromOpWithDU (OP_REQV (IC_RESULT (ic)),
600 OP_SYMBOL (IC_RESULT (ic))->defs,
601 OP_SYMBOL (IC_RESULT (ic))->uses);
602 IC_RESULT (ic)->isaddr = 1;
605 IC_RESULT (ic) = opFromOpWithDU (OP_REQV (IC_RESULT (ic)),
606 OP_SYMBOL (IC_RESULT (ic))->defs,
607 OP_SYMBOL (IC_RESULT (ic))->uses);
611 IS_TRUE_SYMOP (IC_RIGHT (ic)) &&
612 OP_REQV (IC_RIGHT (ic)))
614 IC_RIGHT (ic) = opFromOpWithDU (OP_REQV (IC_RIGHT (ic)),
615 OP_SYMBOL (IC_RIGHT (ic))->defs,
616 OP_SYMBOL (IC_RIGHT (ic))->uses);
617 IC_RIGHT (ic)->isaddr = 0;
621 IS_TRUE_SYMOP (IC_LEFT (ic)) &&
622 OP_REQV (IC_LEFT (ic)))
624 IC_LEFT (ic) = opFromOpWithDU (OP_REQV (IC_LEFT (ic)),
625 OP_SYMBOL (IC_LEFT (ic))->defs,
626 OP_SYMBOL (IC_LEFT (ic))->uses);
627 IC_LEFT (ic)->isaddr = 0;
633 /*-----------------------------------------------------------------*/
634 /* killDeadCode - eliminates dead assignments */
635 /*-----------------------------------------------------------------*/
637 killDeadCode (eBBlock ** ebbs, int count)
644 /* basic algorithm :- */
645 /* first the exclusion rules :- */
646 /* 1. if result is a global or volatile then skip */
647 /* 2. if assignment and result is a temp & isaddr then skip */
648 /* since this means array & pointer access, will be taken */
649 /* care of by alias analysis. */
650 /* 3. if the result is used in the remainder of the block skip */
651 /* 4. if this definition does not reach the end of the block */
652 /* i.e. the result is not present in the outExprs then KILL */
653 /* 5. if it reaches the end of block & is used by some success */
656 /* this whole process is carried on iteratively till no change */
661 /* for all blocks do */
662 for (i = 0; i < count; i++)
666 /* for all instructions in the block do */
667 for (ic = ebbs[i]->sch; ic; ic = ic->next)
677 /* if the result is volatile then continue */
678 if (IC_RESULT (ic) && isOperandVolatile (IC_RESULT (ic), FALSE))
681 /* if the result is a temp & isaddr then skip */
682 if (IC_RESULT (ic) && POINTER_SET (ic))
685 /* if the result is used in the remainder of the */
686 /* block then skip */
687 if (usedInRemaining (IC_RESULT (ic), ic->next))
690 /* does this definition reach the end of the block
691 or the usage is zero then we can kill */
692 if (!bitVectBitValue (ebbs[i]->outDefs, ic->key))
693 kill = 1; /* if not we can kill it */
696 /* if this is a global variable or function parameter */
697 /* we cannot kill anyway */
698 if (isOperandGlobal (IC_RESULT (ic)) ||
699 (OP_SYMBOL (IC_RESULT (ic))->_isparm &&
700 !OP_SYMBOL (IC_RESULT (ic))->ismyparm))
703 /* if we are sure there are no usages */
704 if (bitVectIsZero (OP_USES (IC_RESULT (ic))))
710 /* reset visited flag */
711 for (j = 0; j < count; ebbs[j++]->visited = 0);
713 /* find out if this definition is alive */
714 if (applyToSet (ebbs[i]->succList,
723 /* kill this one if required */
729 remiCodeFromeBBlock (ebbs[i], ic);
731 /* now delete from defUseSet */
732 deleteItemIf (&ebbs[i]->outExprs, ifDiCodeIsX, ic);
733 bitVectUnSetBit (ebbs[i]->outDefs, ic->key);
735 /* and defset of the block */
736 bitVectUnSetBit (ebbs[i]->defSet, ic->key);
738 /* for the left & right remove the usage */
739 if (IS_SYMOP (IC_LEFT (ic)))
740 bitVectUnSetBit (OP_USES (IC_LEFT (ic)), ic->key);
742 if (IS_SYMOP (IC_RIGHT (ic)))
743 bitVectUnSetBit (OP_USES (IC_RIGHT (ic)), ic->key);
746 } /* end of all instructions */
748 if (!ebbs[i]->sch && !ebbs[i]->noPath)
749 disconBBlock (ebbs[i], ebbs, count);
751 } /* end of for all blocks */
755 } /* end of while(1) */
760 /*-----------------------------------------------------------------*/
761 /* printCyclomatic - prints the cyclomatic information */
762 /*-----------------------------------------------------------------*/
764 printCyclomatic (eBBlock ** ebbs, int count)
766 int nEdges = elementsInSet (graphEdges);
769 for (i = 0; i < count; i++)
770 nNodes += (!ebbs[i]->noPath);
772 /* print the information */
773 werror (I_CYCLOMATIC, currFunc->name, nEdges, nNodes, nEdges - nNodes + 2);
776 /*-----------------------------------------------------------------*/
777 /* discardDeadParamReceives - remove any RECEIVE opcodes which */
778 /* refer to dead variables. */
779 /*-----------------------------------------------------------------*/
781 discardDeadParamReceives (eBBlock ** ebbs, int count)
787 for (i = 0; i < count; i++)
789 for (ic = ebbs[i]->sch; ic; ic = ic->next)
791 if (ic->op == RECEIVE)
793 if (IC_RESULT (ic) && OP_SYMBOL (IC_RESULT (ic))
794 && !OP_SYMBOL (IC_RESULT (ic))->used)
797 fprintf (stderr, "discarding dead receive for %s\n",
798 OP_SYMBOL (IC_RESULT (ic))->name);
800 dummyIcode.next = ic->next;
801 remiCodeFromeBBlock (ebbs[i], ic);
809 /*-----------------------------------------------------------------*/
810 /* eBBlockFromiCode - creates extended basic blocks from iCode */
811 /* will return an array of eBBlock pointers */
812 /*-----------------------------------------------------------------*/
814 eBBlockFromiCode (iCode * ic)
816 eBBlock **ebbs = NULL;
824 /* if nothing passed then return nothing */
831 /* optimize the chain for labels & gotos
832 this will eliminate redundant labels and
833 will change jump to jumps by jumps */
834 ic = iCodeLabelOptimize (ic);
836 /* break it down into basic blocks */
837 ebbs = iCodeBreakDown (ic, &count);
840 /* compute the control flow */
841 computeControlFlow (ebbs, count, 0);
843 /* dumpraw if asked for */
844 if (options.dump_raw)
845 dumpEbbsToFileExt (DUMP_RAW0, ebbs, count);
847 /* replace the local variables with their
848 register equivalents : the liveRange computation
849 along with the register allocation will determine
850 if it finally stays in the registers */
851 replaceRegEqv (ebbs, count);
853 /* create loop regions */
854 loops = createLoopRegions (ebbs, count);
856 /* dumpraw if asked for */
857 if (options.dump_raw)
858 dumpEbbsToFileExt (DUMP_RAW1, ebbs, count);
860 /* do common subexpression elimination for each block */
861 change = cseAllBlocks (ebbs, saveCount, FALSE);
863 /* dumpraw if asked for */
864 if (options.dump_raw)
865 dumpEbbsToFileExt (DUMP_CSE, ebbs, count);
867 /* compute the data flow */
868 computeDataFlow (ebbs, saveCount);
870 /* dumpraw if asked for */
871 if (options.dump_raw)
872 dumpEbbsToFileExt (DUMP_DFLOW, ebbs, count);
874 /* global common subexpression elimination */
875 if (optimize.global_cse)
877 change += cseAllBlocks (ebbs, saveCount, FALSE);
878 if (options.dump_gcse)
879 dumpEbbsToFileExt (DUMP_GCSE, ebbs, saveCount);
883 // compute the dataflow only
884 assert(cseAllBlocks (ebbs, saveCount, TRUE)==0);
887 kchange = killDeadCode (ebbs, saveCount);
889 if (options.dump_kill)
890 dumpEbbsToFileExt (DUMP_DEADCODE, ebbs, count);
892 /* do loop optimizations */
893 change += (lchange = loopOptimizations (loops, ebbs, count));
894 if (options.dump_loop)
895 dumpEbbsToFileExt (DUMP_LOOP, ebbs, count);
897 /* recompute the data flow and apply global cse again
898 if loops optimizations or dead code caused a change:
899 loops will brings out of the loop which then may be
900 available for use in the later blocks: dead code
901 elimination could potentially disconnect some blocks
902 conditional flow may be efected so we need to apply
903 subexpression once more */
904 if (lchange || kchange)
906 computeDataFlow (ebbs, saveCount);
907 change += cseAllBlocks (ebbs, saveCount, FALSE);
908 if (options.dump_loop)
909 dumpEbbsToFileExt (DUMP_LOOPG, ebbs, count);
911 /* if loop optimizations caused a change then do
912 dead code elimination once more : this will
913 get rid of the extra assignments to the induction
914 variables created during loop optimizations */
915 killDeadCode (ebbs, saveCount);
917 if (options.dump_loop)
918 dumpEbbsToFileExt (DUMP_LOOPD, ebbs, count);
922 /* sort it back by block number */
923 qsort (ebbs, saveCount, sizeof (eBBlock *), bbNumCompare);
925 if (!options.lessPedantic) {
926 // this is a good place to check missing return values
928 if (!IS_VOID(currFunc->etype)) {
930 // make sure all predecessors of the last block end in a return
931 for (bp=setFirstItem(ebbs[saveCount-1]->predList);
933 bp=setNextItem(ebbs[saveCount-1]->predList)) {
934 if (bp->ech->op != RETURN) {
935 werror (W_VOID_FUNC, currFunc->name);
942 /* if cyclomatic info requested then print it */
943 if (options.cyclomatic)
944 printCyclomatic (ebbs, saveCount);
946 /* convert operations with support routines
947 written in C to function calls : Iam doing
948 this at this point since I want all the
949 operations to be as they are for optimzations */
950 convertToFcall (ebbs, count);
952 /* compute the live ranges */
953 computeLiveRanges (ebbs, count);
955 if (options.dump_range)
956 dumpEbbsToFileExt (DUMP_RANGE, ebbs, count);
958 /* Now that we have the live ranges, discard parameter
959 * receives for unused parameters.
961 discardDeadParamReceives (ebbs, count);
963 /* allocate registers & generate code */
964 port->assignRegisters (ebbs, count);
966 /* throw away blocks */
967 setToNull ((void **) &graphEdges);
974 /* (add-hook 'c-mode-hook (lambda () (setq c-basic-offset 4))) */