Sure,

Is simplier and also handles (A T[-IF] (B T-IF C) -> (A T B) T-IF C
case, which can happen by framing in conditions.

@@ -8380,13 +8400,65 @@ fold_truth_andor (location_t loc, enum t
      lhs is another similar operation, try to merge its rhs with our
      rhs.  Then try to merge our lhs and rhs.  */
   if (TREE_CODE (arg0) == code
-      && 0 != (tem = fold_truthop (loc, code, type,
-                                  TREE_OPERAND (arg0, 1), arg1)))
+      && 0 != (tem = fold_truth_andor_1 (loc, code, type,
+                                        TREE_OPERAND (arg0, 1), arg1)))
     return fold_build2_loc (loc, code, type, TREE_OPERAND (arg0, 0), tem);

-  if ((tem = fold_truthop (loc, code, type, arg0, arg1)) != 0)
+  if ((tem = fold_truth_andor_1 (loc, code, type, arg0, arg1)) != 0)
     return tem;

+  if ((BRANCH_COST (optimize_function_for_speed_p (cfun),
+                   false) >= 2)
+      && LOGICAL_OP_NON_SHORT_CIRCUIT)
+    {
+      enum tree_code ncode, icode;
+
+      ncode = (code == TRUTH_ANDIF_EXPR || code == TRUTH_AND_EXPR)
+             ? TRUTH_AND_EXPR : TRUTH_OR_EXPR;
+      icode = ncode == TRUTH_AND_EXPR ? TRUTH_ANDIF_EXPR : TRUTH_ORIF_EXPR;
+
+      /* Transform ((A AND-IF B) AND[-IF] C) into (A AND-IF (B AND C)),
+        or ((A OR-IF B) OR[-IF] C) into (A OR-IF (B OR C))
+        We don't want to pack more than two leafs to a non-IF AND/OR
+        expression.
+        If tree-code of left-hand operand isn't an AND/OR-IF code and not
+        equal to IF-CODE, then we don't want to add right-hand operand.
+        If the inner right-hand side of left-hand operand has
+        side-effects, or isn't simple, then we can't add to it,
+        as otherwise we might destroy if-sequence.  */
+      if (TREE_CODE (arg0) == icode
+         && simple_operand_p_2 (arg1)
+         /* Needed for sequence points to handle trappings, and
+            side-effects.  */
+         && simple_operand_p_2 (TREE_OPERAND (arg0, 1)))
+       {
+         tem = fold_build2_loc (loc, ncode, type, TREE_OPERAND (arg0, 1),
+                                arg1);
+         return fold_build2_loc (loc, icode, type, TREE_OPERAND (arg0, 0),
+                                 tem);
+       }
+       /* Same as abouve but for (A AND[-IF] (B AND-IF C)) -> ((A AND B) 
AND-IF C),
+          or (A OR[-IF] (B OR-IF C) -> ((A OR B) OR-IF C).  */
+      else if (TREE_CODE (arg1) == icode
+         && simple_operand_p_2 (arg0)
+         /* Needed for sequence points to handle trappings, and
+            side-effects.  */
+         && simple_operand_p_2 (TREE_OPERAND (arg1, 0)))
+       {
+         tem = fold_build2_loc (loc, ncode, type,
+                                arg0, TREE_OPERAND (arg1, 0));
+         return fold_build2_loc (loc, icode, type, tem,
+                                 TREE_OPERAND (arg1, 1));
+       }
+      /* Transform (A AND-IF B) into (A AND B), or (A OR-IF B)
+        into (A OR B).
+        For sequence point consistancy, we need to check for trapping,
+        and side-effects.  */
+      else if (code == icode && simple_operand_p_2 (arg0)
+               && simple_operand_p_2 (arg1))
+       return fold_build2_loc (loc, ncode, type, arg0, arg1);
+    }
+
   return NULL_TREE;
 }

Regards,
Kai

Reply via email to