OSDN Git Service

PR rtl-optimization/28940
[pf3gnuchains/gcc-fork.git] / gcc / tree-gimple.c
index 42a29ad..92c7b41 100644 (file)
@@ -240,6 +240,8 @@ is_gimple_stmt (tree t)
     case OMP_CRITICAL:
     case OMP_RETURN:
     case OMP_CONTINUE:
+    case OMP_ATOMIC_LOAD:
+    case OMP_ATOMIC_STORE:
       /* These are always void.  */
       return true;
 
@@ -436,28 +438,18 @@ is_gimple_call_addr (tree t)
 /* If T makes a function call, return the corresponding CALL_EXPR operand.
    Otherwise, return NULL_TREE.  */
 
-#define GET_CALL_EXPR_IN_BODY do { \
-  /* FIXME tuples: delete the assertion below when conversion complete.  */ \
-  gcc_assert (TREE_CODE (t) != MODIFY_EXPR); \
-  if (TREE_CODE (t) == GIMPLE_MODIFY_STMT) \
-    t = GIMPLE_STMT_OPERAND (t, 1); \
-  if (TREE_CODE (t) == WITH_SIZE_EXPR) \
-    t = TREE_OPERAND (t, 0); \
-  if (TREE_CODE (t) == CALL_EXPR) \
-    return t; \
-  return NULL_TREE; \
-} while (0)
-
 tree
 get_call_expr_in (tree t)
 {
-  GET_CALL_EXPR_IN_BODY;
-}
-
-const_tree
-const_get_call_expr_in (const_tree t)
-{
-  GET_CALL_EXPR_IN_BODY;
+  /* FIXME tuples: delete the assertion below when conversion complete.  */
+  gcc_assert (TREE_CODE (t) != MODIFY_EXPR);
+  if (TREE_CODE (t) == GIMPLE_MODIFY_STMT)
+    t = GIMPLE_STMT_OPERAND (t, 1);
+  if (TREE_CODE (t) == WITH_SIZE_EXPR)
+    t = TREE_OPERAND (t, 0);
+  if (TREE_CODE (t) == CALL_EXPR)
+    return t;
+  return NULL_TREE;
 }
 
 /* Given a memory reference expression T, return its base address.
@@ -531,3 +523,47 @@ recalculate_side_effects (tree t)
       gcc_unreachable ();
    }
 }
+
+/* Canonicalize a tree T for use in a COND_EXPR as conditional.  Returns
+   a canonicalized tree that is valid for a COND_EXPR or NULL_TREE, if
+   we failed to create one.  */
+
+tree
+canonicalize_cond_expr_cond (tree t)
+{
+  /* For (bool)x use x != 0.  */
+  if (TREE_CODE (t) == NOP_EXPR
+      && TREE_TYPE (t) == boolean_type_node)
+    {
+      tree top0 = TREE_OPERAND (t, 0);
+      t = build2 (NE_EXPR, TREE_TYPE (t),
+                 top0, build_int_cst (TREE_TYPE (top0), 0));
+    }
+  /* For !x use x == 0.  */
+  else if (TREE_CODE (t) == TRUTH_NOT_EXPR)
+    {
+      tree top0 = TREE_OPERAND (t, 0);
+      t = build2 (EQ_EXPR, TREE_TYPE (t),
+                 top0, build_int_cst (TREE_TYPE (top0), 0));
+    }
+  /* For cmp ? 1 : 0 use cmp.  */
+  else if (TREE_CODE (t) == COND_EXPR
+          && COMPARISON_CLASS_P (TREE_OPERAND (t, 0))
+          && integer_onep (TREE_OPERAND (t, 1))
+          && integer_zerop (TREE_OPERAND (t, 2)))
+    {
+      tree top0 = TREE_OPERAND (t, 0);
+      t = build2 (TREE_CODE (top0), TREE_TYPE (t),
+                 TREE_OPERAND (top0, 0), TREE_OPERAND (top0, 1));
+    }
+
+  /* A valid conditional for a COND_EXPR is either a gimple value
+     or a comparison with two gimple value operands.  */
+  if (is_gimple_val (t)
+      || (COMPARISON_CLASS_P (t)
+         && is_gimple_val (TREE_OPERAND (t, 0))
+         && is_gimple_val (TREE_OPERAND (t, 1))))
+    return t;
+
+  return NULL_TREE;
+}