aboutsummaryrefslogtreecommitdiff
path: root/gcc/tree-fold-const.h
diff options
context:
space:
mode:
Diffstat (limited to 'gcc/tree-fold-const.h')
-rw-r--r--gcc/tree-fold-const.h245
1 files changed, 245 insertions, 0 deletions
diff --git a/gcc/tree-fold-const.h b/gcc/tree-fold-const.h
new file mode 100644
index 00000000000..42353ea050c
--- /dev/null
+++ b/gcc/tree-fold-const.h
@@ -0,0 +1,245 @@
+/* Fold GENERIC expressions.
+ Copyright (C) 2003, 2004 Free Software Foundation, Inc.
+ Contributed by Sebastian Pop <s.pop@laposte.net>
+
+This file is part of GCC.
+
+GCC is free software; you can redistribute it and/or modify it under
+the terms of the GNU General Public License as published by the Free
+Software Foundation; either version 2, or (at your option) any later
+version.
+
+GCC is distributed in the hope that it will be useful, but WITHOUT ANY
+WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with GCC; see the file COPYING. If not, write to the Free
+Software Foundation, 59 Temple Place - Suite 330, Boston, MA
+02111-1307, USA. */
+
+
+/* This file defines an interface of the tree folder.
+ For the moment, the functions in this file are just wrappers around
+ the "big-ugly" fold function. The final aim is to completely split
+ up the fold function into small pieces in such a way that client
+ passes don't see the changes to the underlying implementation. */
+
+#ifndef GCC_TREE_FOLD_H
+#define GCC_TREE_FOLD_H
+
+
+
+/* Interface for integer operations folding. */
+extern tree tree_fold_lcm (tree, tree);
+extern tree tree_fold_gcd (tree, tree);
+extern tree tree_fold_bezout (tree, tree, tree *, tree *, tree *, tree *);
+extern tree tree_fold_factorial (tree);
+
+
+
+/* Fold the addition. */
+
+static inline tree
+tree_fold_plus (tree type,
+ tree a,
+ tree b)
+{
+ tree res = fold (build (PLUS_EXPR, type, a, b));
+
+ /* Strip away the NON_LVALUE_EXPR: fixes bootstrap on Darwin. */
+ if (TREE_CODE (res) == NON_LVALUE_EXPR)
+ return TREE_OPERAND (res, 0);
+
+ else
+ return res;
+}
+
+/* Fold the substraction. */
+
+static inline tree
+tree_fold_minus (tree type,
+ tree a,
+ tree b)
+{
+ tree res = fold (build (MINUS_EXPR, type, a, b));
+
+ /* Strip away the NON_LVALUE_EXPR: fixes bootstrap on Darwin. */
+ if (TREE_CODE (res) == NON_LVALUE_EXPR)
+ return TREE_OPERAND (res, 0);
+
+ else
+ return res;
+}
+
+/* Fold the multiplication. */
+
+static inline tree
+tree_fold_multiply (tree type,
+ tree a,
+ tree b)
+{
+ tree res = fold (build (MULT_EXPR, type, a, b));
+
+ /* Strip away the NON_LVALUE_EXPR: fixes bootstrap on Darwin. */
+ if (TREE_CODE (res) == NON_LVALUE_EXPR)
+ return TREE_OPERAND (res, 0);
+
+ else
+ return res;
+}
+
+/* Division for integer result that rounds the quotient toward zero. */
+
+static inline tree
+tree_fold_trunc_div (tree type,
+ tree a,
+ tree b)
+{
+ return fold (build (TRUNC_DIV_EXPR, type, a, b));
+}
+
+/* Division for integer result that rounds the quotient toward infinity. */
+
+static inline tree
+tree_fold_ceil_div (tree type,
+ tree a,
+ tree b)
+{
+ return fold (build (CEIL_DIV_EXPR, type, a, b));
+}
+
+/* Division for integer result that rounds toward minus infinity. */
+
+static inline tree
+tree_fold_floor_div (tree type,
+ tree a,
+ tree b)
+{
+ return fold (build (FLOOR_DIV_EXPR, type, a, b));
+}
+
+/* Division which is not supposed to need rounding. */
+
+static inline tree
+tree_fold_exact_div (tree type,
+ tree a,
+ tree b)
+{
+ return fold (build (EXACT_DIV_EXPR, type, a, b));
+}
+
+/* Computes the minimum. */
+
+static inline tree
+tree_fold_min (tree type,
+ tree a,
+ tree b)
+{
+ return fold (build (MIN_EXPR, type, a, b));
+}
+
+/* Computes the maximum. */
+
+static inline tree
+tree_fold_max (tree type,
+ tree a,
+ tree b)
+{
+ return fold (build (MAX_EXPR, type, a, b));
+}
+
+/* Computes the absolute value. */
+
+static inline tree
+tree_fold_abs (tree type,
+ tree a)
+{
+ return fold (build1 (ABS_EXPR, type, a));
+}
+
+/* The binomial coefficient. */
+
+static inline tree
+tree_fold_binomial (tree n,
+ tree k)
+{
+ return tree_fold_exact_div
+ (integer_type_node, tree_fold_factorial (n),
+ tree_fold_multiply
+ (integer_type_node, tree_fold_factorial (k),
+ tree_fold_factorial
+ (tree_fold_minus (integer_type_node, n, k))));
+}
+
+/* Determines whether (a divides b), or (a == gcd (a, b)). */
+
+static inline bool
+tree_fold_divides_p (tree type,
+ tree a,
+ tree b)
+{
+ if (integer_onep (a))
+ return true;
+
+ return integer_zerop
+ (tree_fold_minus
+ (type, a, tree_fold_gcd (a, b)));
+}
+
+/* Given two integer constants A and B, determine whether "A >= B". */
+
+static inline bool
+tree_is_ge (tree a, tree b)
+{
+ tree cmp = fold (build (GE_EXPR, boolean_type_node, a, b));
+ return (tree_int_cst_sgn (cmp) != 0);
+}
+
+/* Given two integer constants A and B, determine whether "A > B". */
+
+static inline bool
+tree_is_gt (tree a, tree b)
+{
+ tree cmp = fold (build (GT_EXPR, boolean_type_node, a, b));
+ return (tree_int_cst_sgn (cmp) != 0);
+}
+
+/* Given two integer constants A and B, determine whether "A <= B". */
+
+static inline bool
+tree_is_le (tree a, tree b)
+{
+ tree cmp = fold (build (LE_EXPR, boolean_type_node, a, b));
+ return (tree_int_cst_sgn (cmp) != 0);
+}
+
+/* Given two integer constants A and B, determine whether "A < B". */
+
+static inline bool
+tree_is_lt (tree a, tree b)
+{
+ tree cmp = fold (build (LT_EXPR, boolean_type_node, a, b));
+ return (tree_int_cst_sgn (cmp) != 0);
+}
+
+/* Given two integer constants A and B, determine whether "A == B". */
+
+static inline bool
+tree_is_eq (tree a, tree b)
+{
+ tree cmp = fold (build (EQ_EXPR, boolean_type_node, a, b));
+ return (tree_int_cst_sgn (cmp) != 0);
+}
+
+/* Given two integer constants A and B, determine whether "A != B". */
+
+static inline bool
+tree_is_ne (tree a, tree b)
+{
+ tree cmp = fold (build (NE_EXPR, boolean_type_node, a, b));
+ return (tree_int_cst_sgn (cmp) != 0);
+}
+
+#endif /* GCC_TREE_FOLD_H */