From: kvigor Date: Fri, 18 Apr 2003 21:03:51 +0000 (+0000) Subject: optimization: replace modulo by a power of two with a bitwise AND X-Git-Url: https://git.gag.com/?a=commitdiff_plain;h=0259910eb50f7d13e3d45da7a8ae230a10d56da1;p=fw%2Fsdcc optimization: replace modulo by a power of two with a bitwise AND git-svn-id: https://sdcc.svn.sourceforge.net/svnroot/sdcc/trunk/sdcc@2538 4a8a32a2-be11-0410-ad9d-d568d2c75423 --- diff --git a/ChangeLog b/ChangeLog index e98bb7b6..2ebb0997 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2003-04-18 Kevin Vigor + + * src/SDCCopt.c: add special case optimization to replace modulo by + a power of two with a bitwise AND. + 2003-04-18 * src/mcs51/gen.c (getFreePtr): fixed bug #635354 diff --git a/src/SDCCopt.c b/src/SDCCopt.c index fd7fadc6..2e1ff9a6 100644 --- a/src/SDCCopt.c +++ b/src/SDCCopt.c @@ -324,6 +324,8 @@ found: } +extern operand *geniCodeRValue (operand *, bool); + /*-----------------------------------------------------------------*/ /* convilong - converts int or long mults or divs to fcalls */ /*-----------------------------------------------------------------*/ @@ -338,8 +340,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++) {