optimization: replace modulo by a power of two with a bitwise AND
authorkvigor <kvigor@4a8a32a2-be11-0410-ad9d-d568d2c75423>
Fri, 18 Apr 2003 21:03:51 +0000 (21:03 +0000)
committerkvigor <kvigor@4a8a32a2-be11-0410-ad9d-d568d2c75423>
Fri, 18 Apr 2003 21:03:51 +0000 (21:03 +0000)
git-svn-id: https://sdcc.svn.sourceforge.net/svnroot/sdcc/trunk/sdcc@2538 4a8a32a2-be11-0410-ad9d-d568d2c75423

ChangeLog
src/SDCCopt.c

index e98bb7b6d33394eb9727468b0c1a206c65768863..2ebb099719b41228e442617f174246deb62e2a19 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,8 @@
+2003-04-18     Kevin Vigor <kevin@vigor.nu>
+
+       * src/SDCCopt.c: add special case optimization to replace modulo by
+         a power of two with a bitwise AND.
+
 2003-04-18    <johan@balder>
 
        * src/mcs51/gen.c (getFreePtr): fixed bug #635354
index fd7fadc6a321a1b0fc9369517e229f1415042f4d..2e1ff9a6f2c65a1ef891b34b196723441501310d 100644 (file)
@@ -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++)
     {