X-Git-Url: https://git.gag.com/?a=blobdiff_plain;f=src%2FSDCCopt.c;h=aea6e373f457f7cc6d4a1ce57d2f68fee469e244;hb=c34cf61917860a821a4631edda334443633805e7;hp=d9183695512c6b1eb5ffa5e856800ffff9db9fca;hpb=24db07e65dc37c465c586f173fcf7d591d5bd7bc;p=fw%2Fsdcc diff --git a/src/SDCCopt.c b/src/SDCCopt.c index d9183695..aea6e373 100644 --- a/src/SDCCopt.c +++ b/src/SDCCopt.c @@ -148,7 +148,8 @@ cnvToFcall (iCode * ic, eBBlock * ebp) { newic = newiCode (IPUSH, right, NULL); newic->parmPush = 1; - bytesPushed+=4; + //bytesPushed+=4; + bytesPushed += getSize(operandType(right)); } addiCodeToeBBlock (ebp, newic, ip); @@ -164,7 +165,8 @@ cnvToFcall (iCode * ic, eBBlock * ebp) { newic = newiCode (IPUSH, left, NULL); newic->parmPush = 1; - bytesPushed+=4; + //bytesPushed+=4; + bytesPushed += getSize(operandType(left)); } addiCodeToeBBlock (ebp, newic, ip); newic->lineno = lineno; @@ -188,6 +190,7 @@ cnvToFloatCast (iCode * ic, eBBlock * ebp) sym_link *type = operandType (IC_RIGHT (ic)); int linenno = ic->lineno; int bwd, su; + int bytesPushed=0; ip = ic->next; /* remove it from the iCode */ @@ -236,6 +239,7 @@ found: { newic = newiCode (IPUSH, IC_RIGHT (ic), NULL); newic->parmPush = 1; + bytesPushed += getSize(operandType(IC_RIGHT(ic))); } addiCodeToeBBlock (ebp, newic, ip); newic->lineno = linenno; @@ -245,6 +249,7 @@ found: /* make the call */ newic = newiCode (CALL, operandFromSymbol (func), NULL); IC_RESULT (newic) = IC_RESULT (ic); + newic->parmBytes+=bytesPushed; addiCodeToeBBlock (ebp, newic, ip); newic->lineno = linenno; @@ -261,6 +266,7 @@ cnvFromFloatCast (iCode * ic, eBBlock * ebp) sym_link *type = operandType (IC_LEFT (ic)); int lineno = ic->lineno; int bwd, su; + int bytesPushed=0; ip = ic->next; /* remove it from the iCode */ @@ -310,6 +316,7 @@ found: { newic = newiCode (IPUSH, IC_RIGHT (ic), NULL); newic->parmPush = 1; + bytesPushed += getSize(operandType(IC_RIGHT(ic))); } addiCodeToeBBlock (ebp, newic, ip); newic->lineno = lineno; @@ -319,11 +326,14 @@ found: /* make the call */ newic = newiCode (CALL, operandFromSymbol (func), NULL); IC_RESULT (newic) = IC_RESULT (ic); + newic->parmBytes+=bytesPushed; addiCodeToeBBlock (ebp, newic, ip); newic->lineno = lineno; } +extern operand *geniCodeRValue (operand *, bool); + /*-----------------------------------------------------------------*/ /* convilong - converts int or long mults or divs to fcalls */ /*-----------------------------------------------------------------*/ @@ -338,8 +348,34 @@ convilong (iCode * ic, eBBlock * ebp, sym_link * type, int op) int su; int bytesPushed=0; - remiCodeFromeBBlock (ebp, ic); - + // Easy special case which avoids function call: modulo by a literal power + // of two can be replaced by a bitwise AND. + if (op == '%' && isOperandLiteral(IC_RIGHT(ic))) + { + unsigned litVal = (unsigned)(operandLitValue(IC_RIGHT(ic))); + + // See if literal value is a power of 2. + while (litVal && !(litVal & 1)) + { + litVal >>= 1; + } + if (litVal) + { + // discard first high bit set. + litVal >>= 1; + } + + if (!litVal) + { + ic->op = BITWISEAND; + IC_RIGHT(ic) = operandFromLit(operandLitValue(IC_RIGHT(ic)) - 1); + return; + } + } + + remiCodeFromeBBlock (ebp, ic); + + /* depending on the type */ for (bwd = 0; bwd < 3; bwd++) { @@ -643,7 +679,10 @@ killDeadCode (eBBlock ** ebbs, int count) if (SKIP_IC (ic) || ic->op == IFX || - ic->op == RETURN) + ic->op == RETURN || + ic->op == DUMMY_READ_VOLATILE || + ic->op == CRITICAL || + ic->op == ENDCRITICAL) continue; /* if the result is volatile then continue */ @@ -653,6 +692,9 @@ killDeadCode (eBBlock ** ebbs, int count) /* if the result is a temp & isaddr then skip */ if (IC_RESULT (ic) && POINTER_SET (ic)) continue; + + if (POINTER_GET (ic) && IS_VOLATILE (operandType (IC_LEFT (ic))->next)) + continue; /* if the result is used in the remainder of the */ /* block then skip */ @@ -689,7 +731,7 @@ killDeadCode (eBBlock ** ebbs, int count) continue; kill = 1; - } + } kill: /* kill this one if required */ @@ -830,7 +872,7 @@ eBBlockFromiCode (iCode * ic) dumpEbbsToFileExt (DUMP_RAW1, ebbs, count); /* do common subexpression elimination for each block */ - change = cseAllBlocks (ebbs, saveCount); + change = cseAllBlocks (ebbs, saveCount, FALSE); /* dumpraw if asked for */ if (options.dump_raw) @@ -846,10 +888,15 @@ eBBlockFromiCode (iCode * ic) /* global common subexpression elimination */ if (optimize.global_cse) { - change += cseAllBlocks (ebbs, saveCount); + change += cseAllBlocks (ebbs, saveCount, FALSE); if (options.dump_gcse) dumpEbbsToFileExt (DUMP_GCSE, ebbs, saveCount); } + else + { + // compute the dataflow only + assert(cseAllBlocks (ebbs, saveCount, TRUE)==0); + } /* kill dead code */ kchange = killDeadCode (ebbs, saveCount); @@ -871,7 +918,7 @@ eBBlockFromiCode (iCode * ic) if (lchange || kchange) { computeDataFlow (ebbs, saveCount); - change += cseAllBlocks (ebbs, saveCount); + change += cseAllBlocks (ebbs, saveCount, FALSE); if (options.dump_loop) dumpEbbsToFileExt (DUMP_LOOPG, ebbs, count); @@ -889,6 +936,25 @@ eBBlockFromiCode (iCode * ic) /* sort it back by block number */ qsort (ebbs, saveCount, sizeof (eBBlock *), bbNumCompare); + if (!options.lessPedantic) { + // this is a good place to check missing return values + if (currFunc) { + // the user is on his own with naked functions... + if (!IS_VOID(currFunc->etype) + && !FUNC_ISNAKED(currFunc->type)) { + eBBlock *bp; + // make sure all predecessors of the last block end in a return + for (bp=setFirstItem(ebbs[saveCount-1]->predList); + bp; + bp=setNextItem(ebbs[saveCount-1]->predList)) { + if (bp->ech->op != RETURN) { + werror (W_VOID_FUNC, currFunc->name); + } + } + } + } + } + /* if cyclomatic info requested then print it */ if (options.cyclomatic) printCyclomatic (ebbs, saveCount); @@ -914,9 +980,9 @@ eBBlockFromiCode (iCode * ic) port->assignRegisters (ebbs, count); /* throw away blocks */ - setToNull ((void **) &graphEdges); + setToNull ((void *) &graphEdges); ebbs = NULL; - + return NULL; }