X-Git-Url: https://git.gag.com/?a=blobdiff_plain;f=src%2FSDCCopt.c;h=94ee6e187b5d0231dc418575b510578387eb20cd;hb=073b50673862372cd3dd8f20e8db68f5d950c0af;hp=05eab6f518d451b39e92f169410e71a509474135;hpb=476f65e63356c85584ef8e42481ddecf5c09e488;p=fw%2Fsdcc diff --git a/src/SDCCopt.c b/src/SDCCopt.c index 05eab6f5..94ee6e18 100644 --- a/src/SDCCopt.c +++ b/src/SDCCopt.c @@ -176,7 +176,10 @@ cnvToFcall (iCode * ic, eBBlock * ebp) IC_RESULT (newic) = IC_RESULT (ic); newic->lineno = lineno; newic->parmBytes+=bytesPushed; - + ebp->hasFcall = 1; + if (currFunc) + FUNC_HASFCALL (currFunc->type) = 1; + if(TARGET_IS_PIC16) { /* normally these functions aren't marked external, so we can use their * _extern field to marked as already added to symbol table */ @@ -264,6 +267,9 @@ found: newic = newiCode (CALL, operandFromSymbol (func), NULL); IC_RESULT (newic) = IC_RESULT (ic); newic->parmBytes+=bytesPushed; + ebp->hasFcall = 1; + if (currFunc) + FUNC_HASFCALL (currFunc->type) = 1; if(TARGET_IS_PIC16) { /* normally these functions aren't marked external, so we can use their @@ -354,6 +360,9 @@ found: newic = newiCode (CALL, operandFromSymbol (func), NULL); IC_RESULT (newic) = IC_RESULT (ic); newic->parmBytes+=bytesPushed; + ebp->hasFcall = 1; + if (currFunc) + FUNC_HASFCALL (currFunc->type) = 1; if(TARGET_IS_PIC16) { /* normally these functions aren't marked external, so we can use their @@ -517,6 +526,9 @@ found: IC_RESULT (newic) = IC_RESULT (ic); newic->lineno = lineno; newic->parmBytes+=bytesPushed; // to clear the stack after the call + ebp->hasFcall = 1; + if (currFunc) + FUNC_HASFCALL (currFunc->type) = 1; if(TARGET_IS_PIC16) { /* normally these functions aren't marked external, so we can use their @@ -611,10 +623,7 @@ convertToFcall (eBBlock ** ebbs, int count) static int isLocalWithoutDef (symbol * sym) { - if (!sym->level) - return 0; - - if (IS_STATIC (sym->etype)) + if (!IS_AUTO (sym)) return 0; if (IS_VOLATILE (sym->type)) @@ -770,6 +779,51 @@ replaceRegEqv (eBBlock ** ebbs, int count) } } +/*-----------------------------------------------------------------*/ +/* findReqv - search for a register equivalent */ +/*-----------------------------------------------------------------*/ +operand * +findReqv (symbol * prereqv, eBBlock ** ebbs, int count) +{ + int i; + iCode * ic; + + /* for all blocks do */ + for (i=0; isch; ic; ic = ic->next) + { + if (ic->op == IFX) + { + if (IS_ITEMP (IC_COND (ic)) + && OP_SYMBOL (IC_COND (ic))->prereqv == prereqv) + return IC_COND (ic); + } + else if (ic->op == JUMPTABLE) + { + if (IS_ITEMP (IC_JTCOND (ic)) + && OP_SYMBOL (IC_JTCOND (ic))->prereqv == prereqv) + return IC_JTCOND (ic); + } + else + { + if (IS_ITEMP (IC_LEFT (ic)) + && OP_SYMBOL (IC_LEFT (ic))->prereqv == prereqv) + return IC_LEFT (ic); + if (IS_ITEMP (IC_RIGHT (ic)) + && OP_SYMBOL (IC_RIGHT (ic))->prereqv == prereqv) + return IC_RIGHT (ic); + if (IS_ITEMP (IC_RESULT (ic)) + && OP_SYMBOL (IC_RESULT (ic))->prereqv == prereqv) + return IC_RESULT (ic); + } + } + } + + return NULL; +} + /*-----------------------------------------------------------------*/ /* killDeadCode - eliminates dead assignments */ /*-----------------------------------------------------------------*/ @@ -829,7 +883,8 @@ killDeadCode (eBBlock ** ebbs, int count) if (IC_RESULT (ic) && POINTER_SET (ic)) continue; - if (POINTER_GET (ic) && IS_VOLATILE (operandType (IC_LEFT (ic))->next)) + if (POINTER_GET (ic) && IS_VOLATILE (operandType (IC_LEFT (ic))->next) + && !SPIL_LOC (IC_RESULT (ic))) continue; /* if the result is used in the remainder of the */ @@ -878,7 +933,10 @@ killDeadCode (eBBlock ** ebbs, int count) bool volRight = IS_SYMOP (IC_RIGHT (ic)) && isOperandVolatile (IC_RIGHT (ic), FALSE); - + /* a dead address-of operation should die, even if volatile */ + if (ic->op == ADDRESS_OF) + volLeft = FALSE; + if (ic->next && ic->seqPoint == ic->next->seqPoint && (ic->next->op == '+' || ic->next->op == '-')) { @@ -890,6 +948,16 @@ killDeadCode (eBBlock ** ebbs, int count) volRight = FALSE; } + if (POINTER_GET (ic) && IS_VOLATILE (operandType (IC_LEFT (ic))->next)) + { + if (SPIL_LOC (IC_RESULT (ic))) + { + IC_RESULT (ic) = newiTempFromOp (IC_RESULT (ic)); + SPIL_LOC (IC_RESULT (ic)) = NULL; + } + continue; + } + change = 1; gchange++; @@ -900,6 +968,29 @@ killDeadCode (eBBlock ** ebbs, int count) /* and defset of the block */ bitVectUnSetBit (ebbs[i]->defSet, ic->key); + /* If this is the last of a register equivalent, */ + /* look for a successor register equivalent. */ + bitVectUnSetBit (OP_DEFS (IC_RESULT (ic)), ic->key); + if (IS_ITEMP (IC_RESULT (ic)) + && OP_SYMBOL (IC_RESULT (ic))->isreqv + && bitVectIsZero (OP_DEFS (IC_RESULT (ic)))) + { + symbol * resultsym = OP_SYMBOL (IC_RESULT (ic)); + symbol * prereqv = resultsym->prereqv; + + if (OP_SYMBOL (prereqv->reqv) == resultsym) + { + operand * newreqv; + + IC_RESULT (ic) = NULL; + newreqv = findReqv (prereqv, ebbs, count); + if (newreqv) + { + prereqv->reqv = newreqv; + } + } + } + /* delete the result */ IC_RESULT (ic) = NULL; @@ -992,6 +1083,76 @@ discardDeadParamReceives (eBBlock ** ebbs, int count) } } +/*-----------------------------------------------------------------*/ +/* optimizeCastCast - remove unneeded intermediate casts. */ +/* Integer promotion may cast (un)signed char to int and then */ +/* recast the int to (un)signed long. If the signedness of the */ +/* char and long are the same, the cast can be safely performed in */ +/* a single step. */ +/*-----------------------------------------------------------------*/ +static void +optimizeCastCast (eBBlock ** ebbs, int count) +{ + int i; + iCode *ic; + iCode *uic; + sym_link * type1; + sym_link * type2; + sym_link * type3; + symbol * sym; + + for (i = 0; i < count; i++) + { + for (ic = ebbs[i]->sch; ic; ic = ic->next) + { + + if (ic->op == CAST && IC_RESULT (ic) && IS_ITEMP (IC_RESULT (ic))) + { + type1 = operandType (IC_RIGHT (ic)); + type2 = operandType (IC_RESULT (ic)); + + /* Look only for a cast from an integer type to an */ + /* integer type that has no loss of bits */ + if (!IS_INTEGRAL (type1) || !IS_INTEGRAL (type2)) + continue; + if (getSize (type2) < getSize (type1)) + continue; + + /* There must be only one use of this first result */ + if (bitVectnBitsOn (OP_USES (IC_RESULT (ic))) != 1) + continue; + + /* This use must be a second cast */ + uic = hTabItemWithKey (iCodehTab, + bitVectFirstBit (OP_USES (IC_RESULT (ic)))); + if (!uic || uic->op != CAST) + continue; + + /* It must be a cast to another integer type that */ + /* has no loss of bits */ + type3 = operandType (IC_RESULT (uic)); + if (!IS_INTEGRAL (type3)) + continue; + if (getSize (type3) < getSize (type2)) + continue; + + /* The signedness between the first and last types */ + /* must match */ + if (SPEC_USIGN (type3) != SPEC_USIGN (type1)) + continue; + + /* Change the first cast to a simple assignment and */ + /* let the second cast do all the work */ + ic->op = '='; + IC_LEFT (ic) = NULL; + sym = OP_SYMBOL (IC_RESULT (ic)); + sym->type = copyLinkChain (type1); + sym->etype = getSpec (sym->type); + } + } + } +} + /*-----------------------------------------------------------------*/ /* eBBlockFromiCode - creates extended basic blocks from iCode */ /* will return an array of eBBlock pointers */ @@ -1049,6 +1210,8 @@ eBBlockFromiCode (iCode * ic) if (options.dump_raw) dumpEbbsToFileExt (DUMP_RAW1, ebbs, count); + optimizeCastCast (ebbs, saveCount); + /* do common subexpression elimination for each block */ change = cseAllBlocks (ebbs, saveCount, FALSE);