* src/SDCCast.c (isLoopCountable): fixed bug #1478316
[fw/sdcc] / src / SDCCast.c
index f27842ea4970e7cfd6cab1294595879fc0e9aef7..beb2becad5976f0a5c19f6986da5e309b42d3427 100644 (file)
@@ -1497,7 +1497,7 @@ isLabelInAst (symbol * label, ast * tree)
 /* isLoopCountable - return true if the loop count can be determi- */
 /* -ned at compile time .                                          */
 /*-----------------------------------------------------------------*/
-bool
+static bool
 isLoopCountable (ast * initExpr, ast * condExpr, ast * loopExpr,
                  symbol ** sym, ast ** init, ast ** end)
 {
@@ -1522,6 +1522,10 @@ isLoopCountable (ast * initExpr, ast * condExpr, ast * loopExpr,
   else
     return FALSE;
 
+  /* don't reverse loop with volatile counter */
+  if (IS_VOLATILE ((*sym)->type))
+    return FALSE;
+
   /* for now the symbol has to be of
      integral type */
   if (!IS_INTEGRAL ((*sym)->type))
@@ -1927,7 +1931,7 @@ isConformingBody (ast * pbody, symbol * sym, ast * body)
 /* if the for loop is reversible. If yes will set the value of     */
 /* the loop control var & init value & termination value           */
 /*-----------------------------------------------------------------*/
-bool
+static bool
 isLoopReversible (ast * loop, symbol ** loopCntrl,
                   ast ** init, ast ** end)
 {
@@ -3629,6 +3633,13 @@ decorateType (ast * tree, RESULT_TYPE resultType)
       changePointer(LTYPE(tree));
       checkTypeSanity(LETYPE(tree), "(cast)");
 
+      /* if 'from' and 'to' are the same remove the superflous cast, */
+      /* this helps other optimizations */
+      if (compareTypeExact (LTYPE(tree), RTYPE(tree), -1) == 1)
+        {
+          return tree->right;
+        }
+
       /* If code memory is read only, then pointers to code memory */
       /* implicitly point to constants -- make this explicit       */
       {
@@ -3916,6 +3927,7 @@ decorateType (ast * tree, RESULT_TYPE resultType)
                 goto errorTreeReturn;
               }
         }
+
       /* if unsigned value < 0  then always false */
       /* if (unsigned value) > 0 then '(unsigned value) ? 1 : 0' */
       if (SPEC_USIGN(LETYPE(tree)) &&
@@ -3943,9 +3955,23 @@ decorateType (ast * tree, RESULT_TYPE resultType)
                                      tree->right); /* val 0 */
               tree->right->lineno = tree->lineno;
               tree->right->left->lineno = tree->lineno;
-              decorateType (tree->right, RESULT_TYPE_NONE);
+              tree->decorated = 0;
+              return decorateType (tree, resultType);
             }
         }
+
+      /* 'ifx (op == 0)' -> 'ifx (!(op))' */
+      if (IS_LITERAL(RTYPE(tree))  &&
+          floatFromVal (valFromType (RETYPE (tree))) == 0 &&
+          tree->opval.op == EQ_OP &&
+          resultType == RESULT_TYPE_IFX)
+        {
+          tree->opval.op = '!';
+          tree->right = NULL;
+          tree->decorated = 0;
+          return decorateType (tree, resultType);
+        }
+
       /* if they are both literal then */
       /* rewrite the tree */
       if (IS_LITERAL (RTYPE (tree)) &&
@@ -3992,7 +4018,7 @@ decorateType (ast * tree, RESULT_TYPE resultType)
         }
 
       LRVAL (tree) = RRVAL (tree) = 1;
-      TTYPE (tree) = TETYPE (tree) = newCharLink ();
+      TTYPE (tree) = TETYPE (tree) = newBoolLink ();
       return tree;
 
       /*------------------------------------------------------------------*/