num)) return false; STRIP_NOPS (chrec); scev = hide_evolution_in_other_loops_than_loop (chrec, loop_num); *res = !tree_contains_chrecs (scev, NULL); return true; } /* Build a polynomial chain of recurrence. */ static inline tree build_polynomial_chrec (unsigned loop_num, tree left, tree right) { bool val; if (left == chrec_dont_know || right == chrec_dont_know) return chrec_dont_know; if (!no_evolution_in_loop_p (left, loop_num, &val) || !val) return chrec_dont_know; /* Types of left and right sides of a chrec should be compatible, but pointer CHRECs are special in that the evolution is of ptroff type. */ if (POINTER_TYPE_P (TREE_TYPE (left))) gcc_checking_assert (ptrofftype_p (TREE_TYPE (right))); else { /* Pointer types should occur only on the left hand side, i.e. in the base of the chrec, and not in the step. */ gcc_checking_assert (!POINTER_TYPE_P (TREE_TYPE (right)) && types_compatible_p (TREE_TYPE (left), TREE_TYPE (right))); } if (chrec_zerop (right)) return left; tree chrec = build2 (POLYNOMIAL_CHREC, TREE_TYPE (left), left, right); CHREC_VARIABLE (chrec) = loop_num; return chrec; } /* Determines whether the expression CHREC is a constant. */ static inline bool evolution_function_is_constant_p (const_tree chrec) { if (chrec == NULL_TREE) return false; if (CONSTANT_CLASS_P (chrec)) return true; return is_gimple_min_invariant (chrec); } /* Determine whether CHREC is an affine evolution function in LOOPNUM. */ static inline bool evolution_function_is_affine_in_loop (const_tree chrec, int loopnum) { if (chrec == NULL_TREE) return false; switch (TREE_CODE (chrec)) { case POLYNOMIAL_CHREC: if (evolution_function_is_invariant_p (CHREC_LEFT (chrec), loopnum) && evolution_function_is_invariant_p (CHREC_RIGHT (chrec), loopnum)) return true; else return false; default: return false; } } /* Determine whether CHREC is an affine evolution function or not. */ static inline bool evolution_function_is_affine_p (const_tree chrec) { return chrec && TREE_CODE (chrec) == POLYNOMIAL_CHREC && evolution_function_is_invariant_p (CHREC_RIGHT (chrec), CHREC_VARIABLE (chrec)) && (TREE_CODE (CHREC_RIGHT (chrec)) != POLYNOMIAL_CHREC || evolution_function_is_affine_p (CHREC_RIGHT (chrec))); } /* Determines whether EXPR does not contains chrec expressions. */ static inline bool tree_does_not_contain_chrecs (const_tree expr) { return !tree_contains_chrecs (expr, NULL); } /* Returns the type of the chrec. */ static inline tree chrec_type (const_tree chrec) { if (automatically_generated_chrec_p (chrec)) return NULL_TREE; return TREE_TYPE (chrec); } static inline tree chrec_fold_op (enum tree_code code, tree type, tree op0, tree op1) { switch (code) { case PLUS_EXPR: return chrec_fold_plus (type, op0, op1); case MINUS_EXPR: return chrec_fold_minus (type, op0, op1); case MULT_EXPR: return chrec_fold_multiply (type, op0, op1); default: gcc_unreachable (); } } #endif /* GCC_TREE_CHREC_H */